summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorBjoern Michaelsen <bjoern.michaelsen@canonical.com>2011-07-24 19:23:00 +0200
committerBjoern Michaelsen <bjoern.michaelsen@canonical.com>2011-07-24 19:23:00 +0200
commit41ce86ad453eefdf1a5f8c5b72f2d0099f3938a7 (patch)
treeb98deba63cc7e874608de37335b533858ad43acc /vcl
parent182488ef1409a0a524e4a3e72d6098efd7bc8479 (diff)
parenta3a5ec733152f282ba243644bced2c3cdecdcf98 (diff)
Merge branch 'master' into feature/gnumake4
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk2
-rw-r--r--vcl/Library_vclplug_gen.mk2
-rw-r--r--vcl/inc/aqua/salconst.h25
-rw-r--r--vcl/inc/glyphcache.hxx3
-rw-r--r--vcl/inc/ios/iosvcltypes.h1
-rw-r--r--vcl/inc/ios/salconst.h (renamed from vcl/inc/unx/cdeint.hxx)25
-rw-r--r--vcl/inc/ios/salctfontutils.hxx (renamed from vcl/inc/unx/dtint.hxx)54
-rw-r--r--vcl/inc/ios/salgdi.h14
-rw-r--r--vcl/inc/unx/saldata.hxx1
-rw-r--r--vcl/inc/unx/saldisp.hxx3
-rw-r--r--vcl/inc/unx/wmadaptor.hxx6
-rw-r--r--vcl/inc/vcl/alpha.hxx125
-rw-r--r--vcl/inc/vcl/svapp.hxx2
-rw-r--r--vcl/ios/source/gdi/salgdi.cxx2476
-rw-r--r--vcl/ios/source/gdi/salvd.cxx260
-rw-r--r--vcl/source/app/svapp.cxx16
-rw-r--r--vcl/source/gdi/alpha.cxx119
-rw-r--r--vcl/source/glyphs/glyphcache.cxx34
-rw-r--r--vcl/unx/generic/app/saldata.cxx2
-rw-r--r--vcl/unx/generic/app/saldisp.cxx67
-rw-r--r--vcl/unx/generic/app/salinst.cxx1
-rw-r--r--vcl/unx/generic/app/salsys.cxx1
-rw-r--r--vcl/unx/generic/app/wmadaptor.cxx123
-rw-r--r--vcl/unx/generic/desktopdetect/desktopdetector.cxx20
-rw-r--r--vcl/unx/generic/fontmanager/helper.cxx6
-rw-r--r--vcl/unx/generic/gdi/cdeint.cxx237
-rw-r--r--vcl/unx/generic/gdi/dtint.cxx143
-rw-r--r--vcl/unx/generic/gdi/salgdi3.cxx61
-rw-r--r--vcl/unx/generic/gdi/salprnpsp.cxx3
-rw-r--r--vcl/unx/generic/plugadapt/salplug.cxx2
-rw-r--r--vcl/unx/generic/printergfx/printerjob.cxx5
-rw-r--r--vcl/unx/generic/printergfx/text_gfx.cxx10
-rw-r--r--vcl/unx/generic/window/salframe.cxx66
-rw-r--r--vcl/unx/kde4/KDEXLib.cxx2
34 files changed, 2936 insertions, 981 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index b67e24cdcd99..e10eb98009da 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -249,6 +249,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/ios/source/app/salinst \
vcl/ios/source/app/salsys \
vcl/ios/source/app/saltimer \
+ vcl/ios/source/gdi/salgdi \
+ vcl/ios/source/gdi/salvd \
))
endif
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 9f7c771ca268..99b319e453fa 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -109,8 +109,6 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
vcl/unx/generic/dtrans/X11_selection \
vcl/unx/generic/dtrans/X11_service \
vcl/unx/generic/dtrans/X11_transferable \
- vcl/unx/generic/gdi/cdeint \
- vcl/unx/generic/gdi/dtint \
vcl/unx/generic/gdi/gcach_xpeer \
vcl/unx/generic/gdi/pspgraphics \
vcl/unx/generic/gdi/salbmp \
diff --git a/vcl/inc/aqua/salconst.h b/vcl/inc/aqua/salconst.h
index 50971a819c09..87bdbf42d5e0 100644
--- a/vcl/inc/aqua/salconst.h
+++ b/vcl/inc/aqua/salconst.h
@@ -33,23 +33,6 @@
// - Constants -
// -------------------
-static const unsigned short kByteMask = 0xFF;
-
-static const unsigned short kOneByte = 8;
-static const unsigned short kTwoBytes = 16;
-
-static const unsigned short kOneBit = 1;
-static const unsigned short kFiveBits = 5;
-static const unsigned short kEightBits = 8;
-static const unsigned short kTenBits = 10;
-static const unsigned short kElevenBits = 11;
-
-static const unsigned short kBlackAndWhite = 1;
-static const unsigned short kFourBitColor = 4;
-static const unsigned short kEightBitColor = 8;
-static const unsigned short kThousandsColor = 16;
-static const unsigned short kTrueColor = 32;
-
static const unsigned long k16BitRedColorMask = 0x00007c00;
static const unsigned long k16BitGreenColorMask = 0x000003e0;
static const unsigned long k16BitBlueColorMask = 0x0000001f;
@@ -58,14 +41,6 @@ static const unsigned long k32BitRedColorMask = 0x00ff0000;
static const unsigned long k32BitGreenColorMask = 0x0000ff00;
static const unsigned long k32BitBlueColorMask = 0x000000ff;
-static const unsigned short kPixMapCmpSizeOneBit = 1;
-static const unsigned short kPixMapCmpSizeFourBits = 4;
-static const unsigned short kPixMapCmpSizeFiveBits = 5;
-static const unsigned short kPixMapCmpSizeEightBits = 8;
-
-static const long kPixMapHRes = 72;
-static const long kPixMapVRes = 72;
-
#endif // _SV_SALCONST_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/glyphcache.hxx b/vcl/inc/glyphcache.hxx
index 42f90672f87b..6cd958d0cb11 100644
--- a/vcl/inc/glyphcache.hxx
+++ b/vcl/inc/glyphcache.hxx
@@ -71,9 +71,7 @@ public:
/*virtual*/ ~GlyphCache();
static GlyphCache& GetInstance();
- void LoadFonts();
- void ClearFontPath();
void AddFontPath( const String& rFontPath );
void AddFontFile( const rtl::OString& rNormalizedName,
int nFaceNum, sal_IntPtr nFontId, const ImplDevFontAttributes&,
@@ -96,7 +94,6 @@ private:
void GrowNotify();
private:
- sal_uLong CalcByteCount() const;
void GarbageCollect();
// the GlyphCache's FontList matches a font request to a serverfont instance
diff --git a/vcl/inc/ios/iosvcltypes.h b/vcl/inc/ios/iosvcltypes.h
index 820547b6a013..d0ef03b9e640 100644
--- a/vcl/inc/ios/iosvcltypes.h
+++ b/vcl/inc/ios/iosvcltypes.h
@@ -29,6 +29,7 @@
#define _IOSVCLTYPES_H
#include "premac.h"
+#import <CoreText/CoreText.h>
#import <UIKit/UIKit.h>
#include "postmac.h"
diff --git a/vcl/inc/unx/cdeint.hxx b/vcl/inc/ios/salconst.h
index c2b7d578b137..87bdbf42d5e0 100644
--- a/vcl/inc/unx/cdeint.hxx
+++ b/vcl/inc/ios/salconst.h
@@ -25,23 +25,22 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#ifndef _SV_CDEINT_HXX
-#define _SV_CDEINT_HXX
-#include <unx/dtint.hxx>
+#ifndef _SV_SALCONST_H
+#define _SV_SALCONST_H
-class CDEIntegrator : public DtIntegrator
-{
- friend DtIntegrator* DtIntegrator::CreateDtIntegrator();
-private:
- CDEIntegrator();
+// -------------------
+// - Constants -
+// -------------------
-public:
- virtual ~CDEIntegrator();
+static const unsigned long k16BitRedColorMask = 0x00007c00;
+static const unsigned long k16BitGreenColorMask = 0x000003e0;
+static const unsigned long k16BitBlueColorMask = 0x0000001f;
- virtual void GetSystemLook( AllSettings& rSettings );
-};
+static const unsigned long k32BitRedColorMask = 0x00ff0000;
+static const unsigned long k32BitGreenColorMask = 0x0000ff00;
+static const unsigned long k32BitBlueColorMask = 0x000000ff;
-#endif
+#endif // _SV_SALCONST_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/dtint.hxx b/vcl/inc/ios/salctfontutils.hxx
index 010a0417d89b..e3f92165086c 100644
--- a/vcl/inc/unx/dtint.hxx
+++ b/vcl/inc/ios/salctfontutils.hxx
@@ -25,50 +25,36 @@
* for a copy of the LGPLv3 License.
*
************************************************************************/
-#ifndef _SV_DTINT_HXX
-#define _SV_DTINT_HXX
-#include <tools/link.hxx>
-#include <tools/string.hxx>
-#include <tools/color.hxx>
-#include <vcl/font.hxx>
-#include "svunx.h"
+#ifndef _SV_SALCGFONTUTILS_HXX
+#define _SV_SALCGFONTUTILS_HXX
-class SalBitmap;
-class SalDisplay;
-class AllSettings;
+class ImplIosFontData;
+class ImplDevFontList;
-enum DtType {
- DtGeneric,
- DtCDE
-};
-
-class DtIntegrator
-{
-protected:
- DtType meType;
- Display* mpDisplay;
- SalDisplay* mpSalDisplay;
- int mnSystemLookCommandProcess;
+#include <CoreText/CoreText.h>
+#include <map>
- DtIntegrator();
-
- static String aHomeDir;
-
+/* This class has the responsibility of assembling a list of fonts
+ available on the system and enabling access to that list.
+ */
+class SystemFontList
+{
public:
- static DtIntegrator* CreateDtIntegrator();
+ SystemFontList();
+ ~SystemFontList();
- virtual ~DtIntegrator();
+ void AnnounceFonts( ImplDevFontList& ) const;
+ ImplIosFontData* GetFontDataFromFont( CGFontRef ) const;
- // SystemLook
- virtual void GetSystemLook( AllSettings& rSettings );
+private:
+ typedef boost::unordered_map<CGFontRef,ImplIosFontData*> IosFontContainer;
+ IosFontContainer maFontContainer;
- DtType GetDtType() { return meType; }
- SalDisplay* GetSalDisplay() { return mpSalDisplay; }
- Display* GetDisplay() { return mpDisplay; }
+ void InitGlyphFallbacks();
};
-#endif
+#endif // _SV_SALCGFONTUTILS_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/ios/salgdi.h b/vcl/inc/ios/salgdi.h
index 51ef49219e9a..0c3e591b3d98 100644
--- a/vcl/inc/ios/salgdi.h
+++ b/vcl/inc/ios/salgdi.h
@@ -49,7 +49,7 @@ class CGRect;
class ImplIosFontData : public ImplFontData
{
public:
- ImplIosFontData( const ImplDevFontAttributes&, NSString * );
+ ImplIosFontData( const ImplDevFontAttributes&, CTFontRef );
virtual ~ImplIosFontData();
@@ -65,6 +65,10 @@ public:
void ReadIosCmapEncoding() const;
bool HasCJKSupport() const;
+protected:
+ friend class IosSalGraphics;
+ const CTFontRef mpFontRef;
+
private:
mutable const ImplFontCharMap* mpCharMap;
mutable vcl::FontCapabilities maFontCapabilities;
@@ -120,7 +124,13 @@ protected:
RGBAColor maFillColor;
// Device Font settings
- const ImplIosFontData* mpIosFontData;
+ const ImplIosFontData* mpIosFontData;
+ /// Font attributes ???
+ NSMutableDictionary* mpAttributes;
+ // text color
+ SalColor mnColor;
+ /// text rotation ???
+ Fixed mnRotation;
/// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
float mfFontStretch;
/// allows text to be rendered without antialiasing
diff --git a/vcl/inc/unx/saldata.hxx b/vcl/inc/unx/saldata.hxx
index 825c148cfa1f..8c2d732f7a07 100644
--- a/vcl/inc/unx/saldata.hxx
+++ b/vcl/inc/unx/saldata.hxx
@@ -57,7 +57,6 @@ typedef unsigned int pthread_t;
class VCLPLUG_GEN_PUBLIC X11SalData : public SalData
{
protected:
- sal_Bool bNoExceptions_;
SalXLib *pXLib_;
SalDisplay *m_pSalDisplay;
pthread_t hMainThread_;
diff --git a/vcl/inc/unx/saldisp.hxx b/vcl/inc/unx/saldisp.hxx
index 194e050df2b0..5f0bc8c11f5f 100644
--- a/vcl/inc/unx/saldisp.hxx
+++ b/vcl/inc/unx/saldisp.hxx
@@ -55,7 +55,6 @@ class SalFrame;
class ColorMask;
namespace vcl_sal { class WMAdaptor; }
-class DtIntegrator;
// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define PROPERTY_SUPPORT_WM_SetPos 0x00000001
@@ -375,7 +374,6 @@ protected:
rtl::OString m_aKeyboardName;
vcl_sal::WMAdaptor* m_pWMAdaptor;
- DtIntegrator* m_pDtIntegrator;
bool m_bXinerama;
std::vector< Rectangle > m_aXineramaScreens;
@@ -497,7 +495,6 @@ public:
{ mpKbdExtension = pKbdExtension; }
const char* GetKeyboardName( bool bRefresh = false );
::vcl_sal::WMAdaptor* getWMAdaptor() const { return m_pWMAdaptor; }
- DtIntegrator* getDtIntegrator() const { return m_pDtIntegrator; }
bool IsXinerama() const { return m_bXinerama; }
const std::vector< Rectangle >& GetXineramaScreens() const { return m_aXineramaScreens; }
XLIB_Window GetRootWindow( int nScreen ) const
diff --git a/vcl/inc/unx/wmadaptor.hxx b/vcl/inc/unx/wmadaptor.hxx
index dc0fe65f290b..5848c6549c46 100644
--- a/vcl/inc/unx/wmadaptor.hxx
+++ b/vcl/inc/unx/wmadaptor.hxx
@@ -323,12 +323,6 @@ public:
Atom getAtom( WMAtom eAtom ) const
{ return m_aWMAtoms[ eAtom ]; }
- /*
- * supports correct positioning
- */
-
- virtual bool supportsICCCMPos () const;
-
int getPositionWinGravity () const
{ return m_nWinGravity; }
int getInitWinGravity() const
diff --git a/vcl/inc/vcl/alpha.hxx b/vcl/inc/vcl/alpha.hxx
index c6f5dd8043fe..6e51a8a2440e 100644
--- a/vcl/inc/vcl/alpha.hxx
+++ b/vcl/inc/vcl/alpha.hxx
@@ -59,45 +59,82 @@ public:
~AlphaMask();
AlphaMask& operator=( const Bitmap& rBitmap );
- AlphaMask& operator=( const AlphaMask& rAlphaMask ) { return (AlphaMask&) Bitmap::operator=( rAlphaMask ); }
- sal_Bool operator!() const { return Bitmap::operator!(); }
- sal_Bool operator==( const AlphaMask& rAlphaMask ) const { return Bitmap::operator==( rAlphaMask ); }
- sal_Bool operator!=( const AlphaMask& rAlphaMask ) const { return Bitmap::operator!=( rAlphaMask ); }
-
- const MapMode& GetPrefMapMode() const { return Bitmap::GetPrefMapMode(); }
- void SetPrefMapMode( const MapMode& rMapMode ) { Bitmap::SetPrefMapMode( rMapMode ); }
-
- const Size& GetPrefSize() const { return Bitmap::GetPrefSize(); }
- void SetPrefSize( const Size& rSize ) { Bitmap::SetPrefSize( rSize ); }
-
- Size GetSizePixel() const { return Bitmap::GetSizePixel(); }
- void SetSizePixel( const Size& rNewSize ) { Bitmap::SetSizePixel( rNewSize ); }
-
- sal_uLong GetSizeBytes() const { return Bitmap::GetSizeBytes(); }
- sal_uLong GetChecksum() const { return Bitmap::GetChecksum(); }
+ AlphaMask& operator=( const AlphaMask& rAlphaMask )
+ {
+ return (AlphaMask&) Bitmap::operator=( rAlphaMask );
+ }
+ sal_Bool operator!() const
+ {
+ return Bitmap::operator!();
+ }
+ sal_Bool operator==( const AlphaMask& rAlphaMask ) const
+ {
+ return Bitmap::operator==( rAlphaMask );
+ }
+ sal_Bool operator!=( const AlphaMask& rAlphaMask ) const
+ {
+ return Bitmap::operator!=( rAlphaMask );
+ }
+
+ const MapMode& GetPrefMapMode() const
+ {
+ return Bitmap::GetPrefMapMode();
+ }
+ void SetPrefMapMode( const MapMode& rMapMode )
+ {
+ Bitmap::SetPrefMapMode( rMapMode );
+ }
+
+ const Size& GetPrefSize() const
+ {
+ return Bitmap::GetPrefSize();
+ }
+ void SetPrefSize( const Size& rSize )
+ {
+ Bitmap::SetPrefSize( rSize );
+ }
+
+ Size GetSizePixel() const
+ {
+ return Bitmap::GetSizePixel();
+ }
+ void SetSizePixel( const Size& rNewSize )
+ {
+ Bitmap::SetSizePixel( rNewSize );
+ }
+
+ sal_uLong GetSizeBytes() const
+ {
+ return Bitmap::GetSizeBytes();
+ }
+ sal_uLong GetChecksum() const
+ {
+ return Bitmap::GetChecksum();
+ }
Bitmap GetBitmap() const;
-public:
-
- sal_Bool Crop( const Rectangle& rRectPixel );
- sal_Bool Expand( sal_uLong nDX, sal_uLong nDY, sal_uInt8* pInitTransparency = NULL );
- sal_Bool CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc, const AlphaMask* pAlphaSrc = NULL );
- sal_Bool Erase( sal_uInt8 cTransparency );
- sal_Bool Invert();
- sal_Bool Mirror( sal_uLong nMirrorFlags );
- sal_Bool Scale( const Size& rNewSize, sal_uLong nScaleFlag = BMP_SCALE_FAST );
- sal_Bool Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag = BMP_SCALE_FAST );
- sal_Bool Rotate( long nAngle10, sal_uInt8 cFillTransparency );
- sal_Bool Replace( const Bitmap& rMask, sal_uInt8 rReplaceTransparency );
- sal_Bool Replace( sal_uInt8 cSearchTransparency, sal_uInt8 cReplaceTransparency, sal_uLong nTol = 0UL );
- sal_Bool Replace( sal_uInt8* pSearchTransparencies, sal_uInt8* pReplaceTransparencies,
- sal_uLong nColorCount, sal_uLong* pTols = NULL );
-
-public:
-
- BitmapReadAccess* AcquireReadAccess() { return Bitmap::AcquireReadAccess(); }
- BitmapWriteAccess* AcquireWriteAccess() { return Bitmap::AcquireWriteAccess(); }
+ sal_Bool CopyPixel(
+ const Rectangle& rRectDst,
+ const Rectangle& rRectSrc,
+ const AlphaMask* pAlphaSrc = NULL
+ );
+ sal_Bool Erase( sal_uInt8 cTransparency );
+ sal_Bool Replace( const Bitmap& rMask, sal_uInt8 rReplaceTransparency );
+ sal_Bool Replace(
+ sal_uInt8 cSearchTransparency,
+ sal_uInt8 cReplaceTransparency,
+ sal_uLong nTol = 0UL
+ );
+
+ BitmapReadAccess* AcquireReadAccess()
+ {
+ return Bitmap::AcquireReadAccess();
+ }
+ BitmapWriteAccess* AcquireWriteAccess()
+ {
+ return Bitmap::AcquireWriteAccess();
+ }
void ReleaseAccess( BitmapReadAccess* pAccess );
typedef vcl::ScopedBitmapAccess< BitmapReadAccess, AlphaMask, &AlphaMask::AcquireReadAccess >
@@ -105,10 +142,18 @@ public:
typedef vcl::ScopedBitmapAccess< BitmapWriteAccess, AlphaMask, &AlphaMask::AcquireWriteAccess >
ScopedWriteAccess;
-public:
-
- sal_Bool Read( SvStream& rIStm, sal_Bool bFileHeader = sal_True ) { return Bitmap::Read( rIStm, bFileHeader ); }
- sal_Bool Write( SvStream& rOStm, sal_Bool bCompressed = sal_True, sal_Bool bFileHeader = sal_True ) const { return Bitmap::Write( rOStm, bCompressed, bFileHeader ); }
+ sal_Bool Read( SvStream& rIStm, sal_Bool bFileHeader = sal_True )
+ {
+ return Bitmap::Read( rIStm, bFileHeader );
+ }
+ sal_Bool Write(
+ SvStream& rOStm,
+ sal_Bool bCompressed = sal_True,
+ sal_Bool bFileHeader = sal_True
+ ) const
+ {
+ return Bitmap::Write( rOStm, bCompressed, bFileHeader );
+ }
friend VCL_DLLPUBLIC SvStream& operator<<( SvStream& rOStm, const BitmapEx& rBitmapEx );
friend VCL_DLLPUBLIC SvStream& operator>>( SvStream& rIStm, BitmapEx& rBitmapEx );
diff --git a/vcl/inc/vcl/svapp.hxx b/vcl/inc/vcl/svapp.hxx
index b233a3c07c03..2c85dbb7de23 100644
--- a/vcl/inc/vcl/svapp.hxx
+++ b/vcl/inc/vcl/svapp.hxx
@@ -382,8 +382,6 @@ public:
static void SetDialogScaleX( short nScale );
- static const String& GetFontPath();
-
static UniqueItemId CreateUniqueId();
static ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDisplayConnection > GetDisplayConnection();
diff --git a/vcl/ios/source/gdi/salgdi.cxx b/vcl/ios/source/gdi/salgdi.cxx
new file mode 100644
index 000000000000..e627c76fe8fe
--- /dev/null
+++ b/vcl/ios/source/gdi/salgdi.cxx
@@ -0,0 +1,2476 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include "osl/file.hxx"
+#include "osl/process.h"
+
+#include "osl/mutex.hxx"
+
+#include "rtl/bootstrap.h"
+#include "rtl/strbuf.hxx"
+
+#include "basegfx/range/b2drectangle.hxx"
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/polygon/b2dpolygontools.hxx"
+#include "basegfx/matrix/b2dhommatrix.hxx"
+#include "basegfx/matrix/b2dhommatrixtools.hxx"
+
+#include "vcl/sysdata.hxx"
+#include "vcl/svapp.hxx"
+
+#include "ios/salconst.h"
+#include "ios/salgdi.h"
+#include "ios/salbmp.h"
+#include "ios/salframe.h"
+#include "ios/salcolorutils.hxx"
+#include "ios/salctfontutils.hxx"
+
+#include "fontsubset.hxx"
+#include "impfont.hxx"
+#include "region.h"
+#include "sallayout.hxx"
+#include "sft.hxx"
+
+
+using namespace vcl;
+
+typedef std::vector<unsigned char> ByteVector;
+
+
+// =======================================================================
+
+ImplIosFontData::ImplIosFontData( const ImplDevFontAttributes& rDFA, CTFontRef pFontRef )
+: ImplFontData( rDFA, 0 )
+, mpFontRef( pFontRef )
+, mpCharMap( NULL )
+, mbOs2Read( false )
+, mbHasOs2Table( false )
+, mbCmapEncodingRead( false )
+, mbHasCJKSupport( false )
+, mbFontCapabilitiesRead( false )
+{
+}
+
+// -----------------------------------------------------------------------
+
+ImplIosFontData::~ImplIosFontData()
+{
+ if( mpCharMap )
+ mpCharMap->DeReference();
+}
+
+// -----------------------------------------------------------------------
+
+sal_IntPtr ImplIosFontData::GetFontId() const
+{
+ return (sal_IntPtr)mpFontRef;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontData* ImplIosFontData::Clone() const
+{
+ ImplIosFontData* pClone = new ImplIosFontData(*this);
+ if( mpCharMap )
+ mpCharMap->AddReference();
+ return pClone;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontEntry* ImplIosFontData::CreateFontInstance(ImplFontSelectData& rFSD) const
+{
+ return new ImplFontEntry(rFSD);
+}
+
+// -----------------------------------------------------------------------
+
+inline FourCharCode GetTag(const char aTagName[5])
+{
+ return (aTagName[0]<<24)+(aTagName[1]<<16)+(aTagName[2]<<8)+(aTagName[3]);
+}
+
+static unsigned GetUShort( const unsigned char* p ){return((p[0]<<8)+p[1]);}
+static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
+
+const ImplFontCharMap* ImplIosFontData::GetImplFontCharMap() const
+{
+ // return the cached charmap
+ if( mpCharMap )
+ return mpCharMap;
+
+ // set the default charmap
+ mpCharMap = ImplFontCharMap::GetDefaultMap();
+ mpCharMap->AddReference();
+
+ // get the CMAP raw data
+ CFDataRef pData = CTFontCopyTable( mpFontRef, kCTFontTableCmap, kCTFontTableOptionNoOptions );
+ if( pData == NULL )
+ return mpCharMap;
+
+ // parse the CMAP
+ CmapResult aCmapResult;
+ if( !ParseCMAP( CFDataGetBytePtr( pData ), CFDataGetLength( pData ), aCmapResult ) ) {
+ CFRelease( pData );
+ return mpCharMap;
+ }
+ CFRelease( pData );
+
+ mpCharMap = new ImplFontCharMap( aCmapResult );
+ mpCharMap->AddReference();
+ return mpCharMap;
+}
+
+bool ImplIosFontData::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
+{
+ // read this only once per font
+ if( mbFontCapabilitiesRead )
+ {
+ rFontCapabilities = maFontCapabilities;
+ return !rFontCapabilities.maUnicodeRange.empty() || !rFontCapabilities.maCodePageRange.empty();
+ }
+ mbFontCapabilitiesRead = true;
+
+ // prepare to get the GSUB table raw data
+ CFDataRef pData = CTFontCopyTable( mpFontRef, kCTFontTableGSUB, kCTFontTableOptionNoOptions );
+ if( pData != NULL )
+ {
+ vcl::getTTScripts(maFontCapabilities.maGSUBScriptTags, CFDataGetBytePtr( pData ), CFDataGetLength( pData ) );
+ CFRelease( pData );
+ }
+ pData = CTFontCopyTable( mpFontRef, kCTFontTableOS2, kCTFontTableOptionNoOptions );
+ if( pData != NULL )
+ {
+ vcl::getTTCoverage(
+ maFontCapabilities.maUnicodeRange,
+ maFontCapabilities.maCodePageRange,
+ CFDataGetBytePtr( pData ), CFDataGetLength( pData ) );
+ CFRelease( pData );
+ }
+ rFontCapabilities = maFontCapabilities;
+ return !rFontCapabilities.maUnicodeRange.empty() || !rFontCapabilities.maCodePageRange.empty();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplIosFontData::ReadOs2Table( void ) const
+{
+ // read this only once per font
+ if( mbOs2Read )
+ return;
+ mbOs2Read = true;
+
+ // get the OS/2 raw data
+ CFDataRef pData = CTFontCopyTable( mpFontRef, kCTFontTableOS2, kCTFontTableOptionNoOptions );
+ if( pData == NULL )
+ return;
+
+ mbHasOs2Table = true;
+
+ // parse the OS/2 raw data
+ // TODO: also analyze panose info, etc.
+
+ // check if the fonts needs the "CJK extra leading" heuristic
+ const sal_uInt32 nVersion = GetUShort( CFDataGetBytePtr( pData ) );
+ if( nVersion >= 0x0001 )
+ {
+ sal_uInt32 ulUnicodeRange2 = GetUInt( CFDataGetBytePtr( pData ) + 46 );
+ if( ulUnicodeRange2 & 0x2DF00000 )
+ mbHasCJKSupport = true;
+ }
+ CFRelease( pData );
+}
+
+void ImplIosFontData::ReadIosCmapEncoding( void ) const
+{
+ // From the ATS framework, not present in the iOS SDK. Define only
+ // the enum values actually used here to avoid copy-pasteing too
+ // much...
+
+ enum {
+ kFontMacintoshPlatform = 1,
+ };
+
+ enum {
+ kFontJapaneseScript = 1,
+ kFontTraditionalChineseScript = 2,
+ kFontChineseScript = kFontTraditionalChineseScript,
+ kFontKoreanScript = 3,
+ kFontSimpleChineseScript = 25,
+ };
+
+ // read this only once per font
+ if( mbCmapEncodingRead )
+ return;
+ mbCmapEncodingRead = true;
+
+ CFDataRef pData = CTFontCopyTable( mpFontRef, kCTFontTableCmap, kCTFontTableOptionNoOptions );
+ DBG_ASSERT( (pData!=NULL), "ImplIosFontData::ReadIosCmapEncoding : CTFontCopyTable failed!\n");
+ if( pData == NULL )
+ return;
+
+ if ( CFDataGetLength( pData ) < 24 ) {
+ CFRelease( pData );
+ return;
+ }
+ if( GetUShort( CFDataGetBytePtr( pData ) ) != 0x0000 ) {
+ CFRelease( pData );
+ return;
+ }
+
+ // check if the fonts needs the "CJK extra leading" heuristic
+ int nSubTables = GetUShort( CFDataGetBytePtr( pData ) + 2 );
+
+ for( const unsigned char* p = CFDataGetBytePtr( pData ) + 4; --nSubTables >= 0; p += 8 )
+ {
+ int nPlatform = GetUShort( p );
+ if( nPlatform == kFontMacintoshPlatform ) {
+ int nEncoding = GetUShort (p + 2 );
+ if( nEncoding == kFontJapaneseScript ||
+ nEncoding == kFontTraditionalChineseScript ||
+ nEncoding == kFontKoreanScript ||
+ nEncoding == kFontSimpleChineseScript )
+ {
+ mbHasCJKSupport = true;
+ break;
+ }
+ }
+ }
+ CFRelease( pData );
+}
+
+// -----------------------------------------------------------------------
+
+bool ImplIosFontData::HasCJKSupport( void ) const
+{
+ ReadOs2Table();
+ if( !mbHasOs2Table )
+ ReadIosCmapEncoding();
+
+ return mbHasCJKSupport;
+}
+
+// =======================================================================
+
+IosSalGraphics::IosSalGraphics()
+ : mpFrame( NULL )
+ , mxLayer( NULL )
+ , mrContext( NULL )
+ , mpXorEmulation( NULL )
+ , mnXorMode( 0 )
+ , mnWidth( 0 )
+ , mnHeight( 0 )
+ , mnBitmapDepth( 0 )
+ , mnRealDPIX( 0 )
+ , mnRealDPIY( 0 )
+ , mfFakeDPIScale( 1.0 )
+ , mxClipPath( NULL )
+ , maLineColor( COL_WHITE )
+ , maFillColor( COL_BLACK )
+ , mpIosFontData( NULL )
+ , mnRotation( 0 )
+ , mfFontStretch( 1.0 )
+ , mbNonAntialiasedText( false )
+ , mbPrinter( false )
+ , mbVirDev( false )
+ , mbWindow( false )
+{
+ // create the style object for font attributes
+ mpAttributes = [NSMutableDictionary dictionary];
+}
+
+// -----------------------------------------------------------------------
+
+IosSalGraphics::~IosSalGraphics()
+{
+/*
+ if( mnUpdateGraphicsEvent )
+ {
+ Application::RemoveUserEvent( mnUpdateGraphicsEvent );
+ }
+*/
+ CGPathRelease( mxClipPath );
+ [mpAttributes release];
+
+ if( mpXorEmulation )
+ delete mpXorEmulation;
+
+ if( mxLayer )
+ CGLayerRelease( mxLayer );
+ else if( mrContext && mbWindow )
+ {
+ // destroy backbuffer bitmap context that we created ourself
+ CGContextRelease( mrContext );
+ mrContext = NULL;
+ // memory is freed automatically by maOwnContextMemory
+ }
+}
+
+bool IosSalGraphics::supportsOperation( OutDevSupportType eType ) const
+{
+ bool bRet = false;
+ switch( eType )
+ {
+ case OutDevSupport_TransparentRect:
+ case OutDevSupport_B2DClip:
+ case OutDevSupport_B2DDraw:
+ bRet = true;
+ break;
+ default: break;
+ }
+ return bRet;
+}
+
+// =======================================================================
+
+void IosSalGraphics::updateResolution()
+{
+ DBG_ASSERT( mbWindow, "updateResolution on inappropriate graphics" );
+
+ initResolution( (mbWindow && mpFrame) ? mpFrame->mpWindow : nil );
+}
+
+void IosSalGraphics::initResolution( UIWindow* )
+{
+ // #i100617# read DPI only once; there is some kind of weird caching going on
+ // if the main screen changes
+ // FIXME: this is really unfortunate and needs to be investigated
+
+ SalData* pSalData = GetSalData();
+ if( pSalData->mnDPIX == 0 || pSalData->mnDPIY == 0 )
+ {
+ UIScreen* pScreen = [UIScreen mainScreen];
+
+ mnRealDPIX = mnRealDPIY = 160;
+ if( pScreen )
+ {
+ mnRealDPIX *= [pScreen scale];
+ mnRealDPIY *= [pScreen scale];
+ }
+ else
+ {
+ OSL_FAIL( "no screen found" );
+ }
+
+ pSalData->mnDPIX = mnRealDPIX;
+ pSalData->mnDPIY = mnRealDPIY;
+ }
+ else
+ {
+ mnRealDPIX = pSalData->mnDPIX;
+ mnRealDPIY = pSalData->mnDPIY;
+ }
+
+ mfFakeDPIScale = 1.0;
+}
+
+void IosSalGraphics::GetResolution( long& rDPIX, long& rDPIY )
+{
+ if( !mnRealDPIY )
+ initResolution( (mbWindow && mpFrame) ? mpFrame->mpWindow : nil );
+
+ rDPIX = static_cast<long>(mfFakeDPIScale * mnRealDPIX);
+ rDPIY = static_cast<long>(mfFakeDPIScale * mnRealDPIY);
+}
+
+void IosSalGraphics::copyResolution( IosSalGraphics& rGraphics )
+{
+ if( !rGraphics.mnRealDPIY && rGraphics.mbWindow && rGraphics.mpFrame )
+ rGraphics.initResolution( rGraphics.mpFrame->mpWindow );
+
+ mnRealDPIX = rGraphics.mnRealDPIX;
+ mnRealDPIY = rGraphics.mnRealDPIY;
+ mfFakeDPIScale = rGraphics.mfFakeDPIScale;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 IosSalGraphics::GetBitCount() const
+{
+ sal_uInt16 nBits = mnBitmapDepth ? mnBitmapDepth : 32;//24;
+ return nBits;
+}
+
+// -----------------------------------------------------------------------
+
+static const basegfx::B2DPoint aHalfPointOfs ( 0.5, 0.5 );
+
+static void AddPolygonToPath( CGMutablePathRef xPath,
+ const ::basegfx::B2DPolygon& rPolygon, bool bClosePath, bool bPixelSnap, bool bLineDraw )
+{
+ // short circuit if there is nothing to do
+ const int nPointCount = rPolygon.count();
+ if( nPointCount <= 0 )
+ return;
+
+ (void)bPixelSnap; // TODO
+ const CGAffineTransform* pTransform = NULL;
+
+ const bool bHasCurves = rPolygon.areControlPointsUsed();
+ for( int nPointIdx = 0, nPrevIdx = 0;; nPrevIdx = nPointIdx++ )
+ {
+ int nClosedIdx = nPointIdx;
+ if( nPointIdx >= nPointCount )
+ {
+ // prepare to close last curve segment if needed
+ if( bClosePath && (nPointIdx == nPointCount) )
+ nClosedIdx = 0;
+ else
+ break;
+ }
+
+ ::basegfx::B2DPoint aPoint = rPolygon.getB2DPoint( nClosedIdx );
+
+ if( bPixelSnap)
+ {
+ // snap device coordinates to full pixels
+ aPoint.setX( basegfx::fround( aPoint.getX() ) );
+ aPoint.setY( basegfx::fround( aPoint.getY() ) );
+ }
+
+ if( bLineDraw )
+ aPoint += aHalfPointOfs;
+
+ if( !nPointIdx ) { // first point => just move there
+ CGPathMoveToPoint( xPath, pTransform, aPoint.getX(), aPoint.getY() );
+ continue;
+ }
+
+ bool bPendingCurve = false;
+ if( bHasCurves )
+ {
+ bPendingCurve = rPolygon.isNextControlPointUsed( nPrevIdx );
+ bPendingCurve |= rPolygon.isPrevControlPointUsed( nClosedIdx );
+ }
+
+ if( !bPendingCurve ) // line segment
+ CGPathAddLineToPoint( xPath, pTransform, aPoint.getX(), aPoint.getY() );
+ else // cubic bezier segment
+ {
+ basegfx::B2DPoint aCP1 = rPolygon.getNextControlPoint( nPrevIdx );
+ basegfx::B2DPoint aCP2 = rPolygon.getPrevControlPoint( nClosedIdx );
+ if( bLineDraw )
+ {
+ aCP1 += aHalfPointOfs;
+ aCP2 += aHalfPointOfs;
+ }
+ CGPathAddCurveToPoint( xPath, pTransform, aCP1.getX(), aCP1.getY(),
+ aCP2.getX(), aCP2.getY(), aPoint.getX(), aPoint.getY() );
+ }
+ }
+
+ if( bClosePath )
+ CGPathCloseSubpath( xPath );
+}
+
+static void AddPolyPolygonToPath( CGMutablePathRef xPath,
+ const ::basegfx::B2DPolyPolygon& rPolyPoly, bool bPixelSnap, bool bLineDraw )
+{
+ // short circuit if there is nothing to do
+ const int nPolyCount = rPolyPoly.count();
+ if( nPolyCount <= 0 )
+ return;
+
+ for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+ {
+ const ::basegfx::B2DPolygon rPolygon = rPolyPoly.getB2DPolygon( nPolyIdx );
+ AddPolygonToPath( xPath, rPolygon, true, bPixelSnap, bLineDraw );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::ResetClipRegion()
+{
+ // release old path and indicate no clipping
+ if( mxClipPath )
+ {
+ CGPathRelease( mxClipPath );
+ mxClipPath = NULL;
+ }
+ if( CheckContext() )
+ SetState();
+}
+
+// -----------------------------------------------------------------------
+
+bool IosSalGraphics::setClipRegion( const Region& i_rClip )
+{
+ // release old clip path
+ if( mxClipPath )
+ {
+ CGPathRelease( mxClipPath );
+ mxClipPath = NULL;
+ }
+ mxClipPath = CGPathCreateMutable();
+
+ // set current path, either as polypolgon or sequence of rectangles
+ if( i_rClip.HasPolyPolygon() )
+ {
+ basegfx::B2DPolyPolygon aClip( const_cast<Region&>(i_rClip).ConvertToB2DPolyPolygon() );
+ AddPolyPolygonToPath( mxClipPath, aClip, !getAntiAliasB2DDraw(), false );
+ }
+ else
+ {
+ long nX, nY, nW, nH;
+ ImplRegionInfo aInfo;
+ bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
+ while( bRegionRect )
+ {
+ if( nW && nH )
+ {
+ CGRect aRect = {{nX,nY}, {nW,nH}};
+ CGPathAddRect( mxClipPath, NULL, aRect );
+ }
+ bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
+ }
+ }
+ // set the current path as clip region
+ if( CheckContext() )
+ SetState();
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetLineColor()
+{
+ maLineColor.SetAlpha( 0.0 ); // transparent
+ if( CheckContext() )
+ CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetLineColor( SalColor nSalColor )
+{
+ maLineColor = RGBAColor( nSalColor );
+ if( CheckContext() )
+ CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetFillColor()
+{
+ maFillColor.SetAlpha( 0.0 ); // transparent
+ if( CheckContext() )
+ CGContextSetFillColor( mrContext, maFillColor.AsArray() );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetFillColor( SalColor nSalColor )
+{
+ maFillColor = RGBAColor( nSalColor );
+ if( CheckContext() )
+ CGContextSetFillColor( mrContext, maFillColor.AsArray() );
+}
+
+// -----------------------------------------------------------------------
+
+static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
+{
+ SalColor nSalColor;
+ if ( nROPColor == SAL_ROP_0 )
+ nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
+ else
+ nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
+ return nSalColor;
+}
+
+void IosSalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ if( ! mbPrinter )
+ SetLineColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ if( ! mbPrinter )
+ SetFillColor( ImplGetROPSalColor( nROPColor ) );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::ImplDrawPixel( long nX, long nY, const RGBAColor& rColor )
+{
+ if( !CheckContext() )
+ return;
+
+ // overwrite the fill color
+ CGContextSetFillColor( mrContext, rColor.AsArray() );
+ // draw 1x1 rect, there is no pixel drawing in Quartz
+ CGRect aDstRect = {{nX,nY,},{1,1}};
+ CGContextFillRect( mrContext, aDstRect );
+ RefreshRect( aDstRect );
+ // reset the fill color
+ CGContextSetFillColor( mrContext, maFillColor.AsArray() );
+}
+
+void IosSalGraphics::drawPixel( long nX, long nY )
+{
+ // draw pixel with current line color
+ ImplDrawPixel( nX, nY, maLineColor );
+}
+
+void IosSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ const RGBAColor aPixelColor( nSalColor );
+ ImplDrawPixel( nX, nY, aPixelColor );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if( nX1 == nX2 && nY1 == nY2 )
+ {
+ // #i109453# platform independent code expects at least one pixel to be drawn
+ drawPixel( nX1, nY1 );
+ return;
+ }
+
+ if( !CheckContext() )
+ return;
+
+ CGContextBeginPath( mrContext );
+ CGContextMoveToPoint( mrContext, static_cast<float>(nX1)+0.5, static_cast<float>(nY1)+0.5 );
+ CGContextAddLineToPoint( mrContext, static_cast<float>(nX2)+0.5, static_cast<float>(nY2)+0.5 );
+ CGContextDrawPath( mrContext, kCGPathStroke );
+
+ Rectangle aRefreshRect( nX1, nY1, nX2, nY2 );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
+{
+ if( !CheckContext() )
+ return;
+
+ CGRect aRect( CGRectMake(nX, nY, nWidth, nHeight) );
+ if( IsPenVisible() )
+ {
+ aRect.origin.x += 0.5;
+ aRect.origin.y += 0.5;
+ aRect.size.width -= 1;
+ aRect.size.height -= 1;
+ }
+
+ if( IsBrushVisible() )
+ CGContextFillRect( mrContext, aRect );
+
+ if( IsPenVisible() )
+ CGContextStrokeRect( mrContext, aRect );
+
+ RefreshRect( nX, nY, nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+
+static void getBoundRect( sal_uLong nPoints, const SalPoint *pPtAry, long &rX, long& rY, long& rWidth, long& rHeight )
+{
+ long nX1 = pPtAry->mnX;
+ long nX2 = nX1;
+ long nY1 = pPtAry->mnY;
+ long nY2 = nY1;
+ for( sal_uLong n = 1; n < nPoints; n++ )
+ {
+ if( pPtAry[n].mnX < nX1 )
+ nX1 = pPtAry[n].mnX;
+ else if( pPtAry[n].mnX > nX2 )
+ nX2 = pPtAry[n].mnX;
+
+ if( pPtAry[n].mnY < nY1 )
+ nY1 = pPtAry[n].mnY;
+ else if( pPtAry[n].mnY > nY2 )
+ nY2 = pPtAry[n].mnY;
+ }
+ rX = nX1;
+ rY = nY1;
+ rWidth = nX2 - nX1 + 1;
+ rHeight = nY2 - nY1 + 1;
+}
+
+static inline void alignLinePoint( const SalPoint* i_pIn, float& o_fX, float& o_fY )
+{
+ o_fX = static_cast<float>(i_pIn->mnX ) + 0.5;
+ o_fY = static_cast<float>(i_pIn->mnY ) + 0.5;
+}
+
+void IosSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint *pPtAry )
+{
+ if( nPoints < 1 )
+ return;
+ if( !CheckContext() )
+ return;
+
+ long nX = 0, nY = 0, nWidth = 0, nHeight = 0;
+ getBoundRect( nPoints, pPtAry, nX, nY, nWidth, nHeight );
+
+ float fX, fY;
+
+ CGContextBeginPath( mrContext );
+ alignLinePoint( pPtAry, fX, fY );
+ CGContextMoveToPoint( mrContext, fX, fY );
+ pPtAry++;
+ for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
+ {
+ alignLinePoint( pPtAry, fX, fY );
+ CGContextAddLineToPoint( mrContext, fX, fY );
+ }
+ CGContextDrawPath( mrContext, kCGPathStroke );
+
+ RefreshRect( nX, nY, nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint *pPtAry )
+{
+ if( nPoints <= 1 )
+ return;
+ if( !CheckContext() )
+ return;
+
+ long nX = 0, nY = 0, nWidth = 0, nHeight = 0;
+ getBoundRect( nPoints, pPtAry, nX, nY, nWidth, nHeight );
+
+ CGPathDrawingMode eMode;
+ if( IsBrushVisible() && IsPenVisible() )
+ eMode = kCGPathEOFillStroke;
+ else if( IsPenVisible() )
+ eMode = kCGPathStroke;
+ else if( IsBrushVisible() )
+ eMode = kCGPathEOFill;
+ else
+ return;
+
+ CGContextBeginPath( mrContext );
+
+ if( IsPenVisible() )
+ {
+ float fX, fY;
+ alignLinePoint( pPtAry, fX, fY );
+ CGContextMoveToPoint( mrContext, fX, fY );
+ pPtAry++;
+ for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
+ {
+ alignLinePoint( pPtAry, fX, fY );
+ CGContextAddLineToPoint( mrContext, fX, fY );
+ }
+ }
+ else
+ {
+ CGContextMoveToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
+ pPtAry++;
+ for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
+ CGContextAddLineToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
+ }
+
+ CGContextDrawPath( mrContext, eMode );
+ RefreshRect( nX, nY, nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawPolyPolygon( sal_uLong nPolyCount, const sal_uLong *pPoints, PCONSTSALPOINT *ppPtAry )
+{
+ if( nPolyCount <= 0 )
+ return;
+ if( !CheckContext() )
+ return;
+
+ // find bound rect
+ long leftX = 0, topY = 0, maxWidth = 0, maxHeight = 0;
+ getBoundRect( pPoints[0], ppPtAry[0], leftX, topY, maxWidth, maxHeight );
+ for( sal_uLong n = 1; n < nPolyCount; n++ )
+ {
+ long nX = leftX, nY = topY, nW = maxWidth, nH = maxHeight;
+ getBoundRect( pPoints[n], ppPtAry[n], nX, nY, nW, nH );
+ if( nX < leftX )
+ {
+ maxWidth += leftX - nX;
+ leftX = nX;
+ }
+ if( nY < topY )
+ {
+ maxHeight += topY - nY;
+ topY = nY;
+ }
+ if( nX + nW > leftX + maxWidth )
+ maxWidth = nX + nW - leftX;
+ if( nY + nH > topY + maxHeight )
+ maxHeight = nY + nH - topY;
+ }
+
+ // prepare drawing mode
+ CGPathDrawingMode eMode;
+ if( IsBrushVisible() && IsPenVisible() )
+ eMode = kCGPathEOFillStroke;
+ else if( IsPenVisible() )
+ eMode = kCGPathStroke;
+ else if( IsBrushVisible() )
+ eMode = kCGPathEOFill;
+ else
+ return;
+
+ // convert to CGPath
+ CGContextBeginPath( mrContext );
+ if( IsPenVisible() )
+ {
+ for( sal_uLong nPoly = 0; nPoly < nPolyCount; nPoly++ )
+ {
+ const sal_uLong nPoints = pPoints[nPoly];
+ if( nPoints > 1 )
+ {
+ const SalPoint *pPtAry = ppPtAry[nPoly];
+ float fX, fY;
+ alignLinePoint( pPtAry, fX, fY );
+ CGContextMoveToPoint( mrContext, fX, fY );
+ pPtAry++;
+ for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
+ {
+ alignLinePoint( pPtAry, fX, fY );
+ CGContextAddLineToPoint( mrContext, fX, fY );
+ }
+ CGContextClosePath(mrContext);
+ }
+ }
+ }
+ else
+ {
+ for( sal_uLong nPoly = 0; nPoly < nPolyCount; nPoly++ )
+ {
+ const sal_uLong nPoints = pPoints[nPoly];
+ if( nPoints > 1 )
+ {
+ const SalPoint *pPtAry = ppPtAry[nPoly];
+ CGContextMoveToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
+ pPtAry++;
+ for( sal_uLong nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ )
+ CGContextAddLineToPoint( mrContext, pPtAry->mnX, pPtAry->mnY );
+ CGContextClosePath(mrContext);
+ }
+ }
+ }
+
+ CGContextDrawPath( mrContext, eMode );
+
+ RefreshRect( leftX, topY, maxWidth, maxHeight );
+}
+
+// -----------------------------------------------------------------------
+
+bool IosSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly,
+ double fTransparency )
+{
+ // short circuit if there is nothing to do
+ const int nPolyCount = rPolyPoly.count();
+ if( nPolyCount <= 0 )
+ return true;
+
+ // ignore invisible polygons
+ if( (fTransparency >= 1.0) || (fTransparency < 0) )
+ return true;
+
+ // setup poly-polygon path
+ CGMutablePathRef xPath = CGPathCreateMutable();
+ for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+ {
+ const ::basegfx::B2DPolygon rPolygon = rPolyPoly.getB2DPolygon( nPolyIdx );
+ AddPolygonToPath( xPath, rPolygon, true, !getAntiAliasB2DDraw(), IsPenVisible() );
+ }
+
+ const CGRect aRefreshRect = CGPathGetBoundingBox( xPath );
+#ifndef NO_I97317_WORKAROUND
+ // #i97317# workaround for Quartz having problems with drawing small polygons
+ if( ! ((aRefreshRect.size.width <= 0.125) && (aRefreshRect.size.height <= 0.125)) )
+#endif
+ {
+ // use the path to prepare the graphics context
+ CGContextSaveGState( mrContext );
+ CGContextBeginPath( mrContext );
+ CGContextAddPath( mrContext, xPath );
+
+ // draw path with antialiased polygon
+ CGContextSetShouldAntialias( mrContext, true );
+ CGContextSetAlpha( mrContext, 1.0 - fTransparency );
+ CGContextDrawPath( mrContext, kCGPathEOFillStroke );
+ CGContextRestoreGState( mrContext );
+
+ // mark modified rectangle as updated
+ RefreshRect( aRefreshRect );
+ }
+
+ CGPathRelease( xPath );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+bool IosSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon& rPolyLine,
+ double fTransparency,
+ const ::basegfx::B2DVector& rLineWidths,
+ basegfx::B2DLineJoin eLineJoin )
+{
+ // short circuit if there is nothing to do
+ const int nPointCount = rPolyLine.count();
+ if( nPointCount <= 0 )
+ return true;
+
+ // reject requests that cannot be handled yet
+ if( rLineWidths.getX() != rLineWidths.getY() )
+ return false;
+
+ // #i101491# Ios does not support B2DLINEJOIN_NONE; return false to use
+ // the fallback (own geometry preparation)
+ // #i104886# linejoin-mode and thus the above only applies to "fat" lines
+ if( (basegfx::B2DLINEJOIN_NONE == eLineJoin)
+ && (rLineWidths.getX() > 1.3) )
+ return false;
+
+ // setup line attributes
+ CGLineJoin aCGLineJoin = kCGLineJoinMiter;
+ switch( eLineJoin ) {
+ case ::basegfx::B2DLINEJOIN_NONE: aCGLineJoin = /*TODO?*/kCGLineJoinMiter; break;
+ case ::basegfx::B2DLINEJOIN_MIDDLE: aCGLineJoin = /*TODO?*/kCGLineJoinMiter; break;
+ case ::basegfx::B2DLINEJOIN_BEVEL: aCGLineJoin = kCGLineJoinBevel; break;
+ case ::basegfx::B2DLINEJOIN_MITER: aCGLineJoin = kCGLineJoinMiter; break;
+ case ::basegfx::B2DLINEJOIN_ROUND: aCGLineJoin = kCGLineJoinRound; break;
+ }
+
+ // setup poly-polygon path
+ CGMutablePathRef xPath = CGPathCreateMutable();
+ AddPolygonToPath( xPath, rPolyLine, rPolyLine.isClosed(), !getAntiAliasB2DDraw(), true );
+
+ const CGRect aRefreshRect = CGPathGetBoundingBox( xPath );
+#ifndef NO_I97317_WORKAROUND
+ // #i97317# workaround for Quartz having problems with drawing small polygons
+ if( ! ((aRefreshRect.size.width <= 0.125) && (aRefreshRect.size.height <= 0.125)) )
+#endif
+ {
+ // use the path to prepare the graphics context
+ CGContextSaveGState( mrContext );
+ CGContextAddPath( mrContext, xPath );
+ // draw path with antialiased line
+ CGContextSetShouldAntialias( mrContext, true );
+ CGContextSetAlpha( mrContext, 1.0 - fTransparency );
+ CGContextSetLineJoin( mrContext, aCGLineJoin );
+ CGContextSetLineWidth( mrContext, rLineWidths.getX() );
+ CGContextDrawPath( mrContext, kCGPathStroke );
+ CGContextRestoreGState( mrContext );
+
+ // mark modified rectangle as updated
+ RefreshRect( aRefreshRect );
+ }
+
+ CGPathRelease( xPath );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalGraphics::drawPolyLineBezier( sal_uLong, const SalPoint*, const sal_uInt8* )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalGraphics::drawPolygonBezier( sal_uLong, const SalPoint*, const sal_uInt8* )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalGraphics::drawPolyPolygonBezier( sal_uLong, const sal_uLong*,
+ const SalPoint* const*, const sal_uInt8* const* )
+{
+ return sal_False;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGraphics )
+{
+ if( !pSrcGraphics )
+ pSrcGraphics = this;
+
+ //from unix salgdi2.cxx
+ //[FIXME] find a better way to prevent calc from crashing when width and height are negative
+ if( pPosAry->mnSrcWidth <= 0
+ || pPosAry->mnSrcHeight <= 0
+ || pPosAry->mnDestWidth <= 0
+ || pPosAry->mnDestHeight <= 0 )
+ {
+ return;
+ }
+
+ // accelerate trivial operations
+ /*const*/ IosSalGraphics* pSrc = static_cast<IosSalGraphics*>(pSrcGraphics);
+ const bool bSameGraphics = (this == pSrc) || (mbWindow && mpFrame && pSrc->mbWindow && (mpFrame == pSrc->mpFrame));
+ if( bSameGraphics
+ && (pPosAry->mnSrcWidth == pPosAry->mnDestWidth)
+ && (pPosAry->mnSrcHeight == pPosAry->mnDestHeight))
+ {
+ // short circuit if there is nothing to do
+ if( (pPosAry->mnSrcX == pPosAry->mnDestX)
+ && (pPosAry->mnSrcY == pPosAry->mnDestY))
+ return;
+ // use copyArea() if source and destination context are identical
+ copyArea( pPosAry->mnDestX, pPosAry->mnDestY, pPosAry->mnSrcX, pPosAry->mnSrcY,
+ pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, 0 );
+ return;
+ }
+
+ ApplyXorContext();
+ pSrc->ApplyXorContext();
+
+ DBG_ASSERT( pSrc->mxLayer!=NULL, "IosSalGraphics::copyBits() from non-layered graphics" );
+
+ const CGPoint aDstPoint = { +pPosAry->mnDestX - pPosAry->mnSrcX, pPosAry->mnDestY - pPosAry->mnSrcY };
+ if( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth && pPosAry->mnSrcHeight == pPosAry->mnDestHeight) &&
+ (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher
+ {
+ // in XOR mode the drawing context is redirected to the XOR mask
+ // if source and target are identical then copyBits() paints onto the target context though
+ CGContextRef xCopyContext = mrContext;
+ if( mpXorEmulation && mpXorEmulation->IsEnabled() )
+ if( pSrcGraphics == this )
+ xCopyContext = mpXorEmulation->GetTargetContext();
+
+ CGContextSaveGState( xCopyContext );
+ const CGRect aDstRect = { {pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight} };
+ CGContextClipToRect( xCopyContext, aDstRect );
+
+ // draw at new destination
+ // NOTE: flipped drawing gets disabled for this, else the subimage would be drawn upside down
+ if( pSrc->IsFlipped() )
+ { CGContextTranslateCTM( xCopyContext, 0, +mnHeight ); CGContextScaleCTM( xCopyContext, +1, -1 ); }
+ // TODO: pSrc->size() != this->size()
+ ::CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, pSrc->mxLayer );
+ CGContextRestoreGState( xCopyContext );
+ // mark the destination rectangle as updated
+ RefreshRect( aDstRect );
+ }
+ else
+ {
+ SalBitmap* pBitmap = pSrc->getBitmap( pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight );
+
+ if( pBitmap )
+ {
+ SalTwoRect aPosAry( *pPosAry );
+ aPosAry.mnSrcX = 0;
+ aPosAry.mnSrcY = 0;
+ drawBitmap( &aPosAry, *pBitmap );
+ delete pBitmap;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY, long nSrcWidth, long nSrcHeight, sal_uInt16 /*nFlags*/ )
+{
+ ApplyXorContext();
+
+ DBG_ASSERT( mxLayer!=NULL, "IosSalGraphics::copyArea() for non-layered graphics" );
+
+ // in XOR mode the drawing context is redirected to the XOR mask
+ // copyArea() always works on the target context though
+ CGContextRef xCopyContext = mrContext;
+ if( mpXorEmulation && mpXorEmulation->IsEnabled() )
+ xCopyContext = mpXorEmulation->GetTargetContext();
+
+ // drawing a layer onto its own context causes trouble on OSX => copy it first
+ // TODO: is it possible to get rid of this unneeded copy more often?
+ // e.g. on OSX>=10.5 only this situation causes problems:
+ // mnBitmapDepth && (aDstPoint.x + pSrc->mnWidth) > mnWidth
+ CGLayerRef xSrcLayer = mxLayer;
+ // TODO: if( mnBitmapDepth > 0 )
+ {
+ const CGSize aSrcSize = { nSrcWidth, nSrcHeight };
+ xSrcLayer = ::CGLayerCreateWithContext( xCopyContext, aSrcSize, NULL );
+ const CGContextRef xSrcContext = CGLayerGetContext( xSrcLayer );
+ CGPoint aSrcPoint = { -nSrcX, -nSrcY };
+ if( IsFlipped() )
+ {
+ ::CGContextTranslateCTM( xSrcContext, 0, +nSrcHeight );
+ ::CGContextScaleCTM( xSrcContext, +1, -1 );
+ aSrcPoint.y = (nSrcY + nSrcHeight) - mnHeight;
+ }
+ ::CGContextDrawLayerAtPoint( xSrcContext, aSrcPoint, mxLayer );
+ }
+
+ // draw at new destination
+ const CGPoint aDstPoint = { +nDstX, +nDstY };
+ ::CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, xSrcLayer );
+
+ // cleanup
+ if( xSrcLayer != mxLayer )
+ CGLayerRelease( xSrcLayer );
+
+ // mark the destination rectangle as updated
+ RefreshRect( nDstX, nDstY, nSrcWidth, nSrcHeight );
+
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap )
+{
+ if( !CheckContext() )
+ return;
+
+ const IosSalBitmap& rBitmap = static_cast<const IosSalBitmap&>(rSalBitmap);
+ CGImageRef xImage = rBitmap.CreateCroppedImage( (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight );
+ if( !xImage )
+ return;
+
+ const CGRect aDstRect = {{pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight}};
+ CGContextDrawImage( mrContext, aDstRect, xImage );
+ CGImageRelease( xImage );
+ RefreshRect( aDstRect );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,SalColor )
+{
+ OSL_FAIL("not implemented for color masking!");
+ drawBitmap( pPosAry, rSalBitmap );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap )
+{
+ if( !CheckContext() )
+ return;
+
+ const IosSalBitmap& rBitmap = static_cast<const IosSalBitmap&>(rSalBitmap);
+ const IosSalBitmap& rMask = static_cast<const IosSalBitmap&>(rTransparentBitmap);
+ CGImageRef xMaskedImage( rBitmap.CreateWithMask( rMask, pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ) );
+ if( !xMaskedImage )
+ return;
+
+ const CGRect aDstRect = {{pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight}};
+ CGContextDrawImage( mrContext, aDstRect, xMaskedImage );
+ CGImageRelease( xMaskedImage );
+ RefreshRect( aDstRect );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::drawMask( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor )
+{
+ if( !CheckContext() )
+ return;
+
+ const IosSalBitmap& rBitmap = static_cast<const IosSalBitmap&>(rSalBitmap);
+ CGImageRef xImage = rBitmap.CreateColorMask( pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, nMaskColor );
+ if( !xImage )
+ return;
+
+ const CGRect aDstRect = {{pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight}};
+ CGContextDrawImage( mrContext, aDstRect, xImage );
+ CGImageRelease( xImage );
+ RefreshRect( aDstRect );
+}
+
+// -----------------------------------------------------------------------
+
+SalBitmap* IosSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
+{
+ DBG_ASSERT( mxLayer, "IosSalGraphics::getBitmap() with no layer" );
+
+ ApplyXorContext();
+
+ IosSalBitmap* pBitmap = new IosSalBitmap;
+ if( !pBitmap->Create( mxLayer, mnBitmapDepth, nX, nY, nDX, nDY, !mbWindow ) )
+ {
+ delete pBitmap;
+ pBitmap = NULL;
+ }
+
+ return pBitmap;
+}
+
+// -----------------------------------------------------------------------
+
+SalColor IosSalGraphics::getPixel( long nX, long nY )
+{
+ // return default value on printers or when out of bounds
+ if( !mxLayer
+ || (nX < 0) || (nX >= mnWidth)
+ || (nY < 0) || (nY >= mnHeight))
+ return COL_BLACK;
+
+ // prepare creation of matching a CGBitmapContext
+ CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big;
+#if __BIG_ENDIAN__
+ struct{ unsigned char b, g, r, a; } aPixel;
+#else
+ struct{ unsigned char a, r, g, b; } aPixel;
+#endif
+
+ // create a one-pixel bitmap context
+ // TODO: is it worth to cache it?
+ CGContextRef xOnePixelContext = ::CGBitmapContextCreate( &aPixel,
+ 1, 1, 8, sizeof(aPixel), aCGColorSpace, aCGBmpInfo );
+
+ // update this graphics layer
+ ApplyXorContext();
+
+ // copy the requested pixel into the bitmap context
+ if( IsFlipped() )
+ nY = mnHeight - nY;
+ const CGPoint aCGPoint = {-nX, -nY};
+ CGContextDrawLayerAtPoint( xOnePixelContext, aCGPoint, mxLayer );
+ CGContextRelease( xOnePixelContext );
+
+ SalColor nSalColor = MAKE_SALCOLOR( aPixel.r, aPixel.g, aPixel.b );
+ return nSalColor;
+}
+
+// -----------------------------------------------------------------------
+
+
+static void DrawPattern50( void*, CGContextRef rContext )
+{
+ static const CGRect aRects[2] = { { {0,0}, { 2, 2 } }, { { 2, 2 }, { 2, 2 } } };
+ CGContextAddRects( rContext, aRects, 2 );
+ CGContextFillPath( rContext );
+}
+
+void IosSalGraphics::Pattern50Fill()
+{
+ static const float aFillCol[4] = { 1,1,1,1 };
+ static const CGPatternCallbacks aCallback = { 0, &DrawPattern50, NULL };
+ if( ! GetSalData()->mxP50Space )
+ GetSalData()->mxP50Space = CGColorSpaceCreatePattern( GetSalData()->mxRGBSpace );
+ if( ! GetSalData()->mxP50Pattern )
+ GetSalData()->mxP50Pattern = CGPatternCreate( NULL, CGRectMake( 0, 0, 4, 4 ),
+ CGAffineTransformIdentity, 4, 4,
+ kCGPatternTilingConstantSpacing,
+ false, &aCallback );
+
+ CGContextSetFillColorSpace( mrContext, GetSalData()->mxP50Space );
+ CGContextSetFillPattern( mrContext, GetSalData()->mxP50Pattern, aFillCol );
+ CGContextFillPath( mrContext );
+}
+
+void IosSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
+{
+ if ( CheckContext() )
+ {
+ CGRect aCGRect = CGRectMake( nX, nY, nWidth, nHeight);
+ CGContextSaveGState(mrContext);
+
+ if ( nFlags & SAL_INVERT_TRACKFRAME )
+ {
+ const float dashLengths[2] = { 4.0, 4.0 }; // for drawing dashed line
+ CGContextSetBlendMode( mrContext, kCGBlendModeDifference );
+ CGContextSetRGBStrokeColor ( mrContext, 1.0, 1.0, 1.0, 1.0 );
+ CGContextSetLineDash ( mrContext, 0, dashLengths, 2 );
+ CGContextSetLineWidth( mrContext, 2.0);
+ CGContextStrokeRect ( mrContext, aCGRect );
+ }
+ else if ( nFlags & SAL_INVERT_50 )
+ {
+ //CGContextSetAllowsAntialiasing( mrContext, false );
+ CGContextSetBlendMode(mrContext, kCGBlendModeDifference);
+ CGContextAddRect( mrContext, aCGRect );
+ Pattern50Fill();
+ }
+ else // just invert
+ {
+ CGContextSetBlendMode(mrContext, kCGBlendModeDifference);
+ CGContextSetRGBFillColor ( mrContext,1.0, 1.0, 1.0 , 1.0 );
+ CGContextFillRect ( mrContext, aCGRect );
+ }
+ CGContextRestoreGState( mrContext);
+ RefreshRect( aCGRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInvert nSalFlags )
+{
+ CGPoint* CGpoints ;
+ if ( CheckContext() )
+ {
+ CGContextSaveGState(mrContext);
+ CGpoints = makeCGptArray(nPoints,pPtAry);
+ CGContextAddLines ( mrContext, CGpoints, nPoints );
+ if ( nSalFlags & SAL_INVERT_TRACKFRAME )
+ {
+ const float dashLengths[2] = { 4.0, 4.0 }; // for drawing dashed line
+ CGContextSetBlendMode( mrContext, kCGBlendModeDifference );
+ CGContextSetRGBStrokeColor ( mrContext, 1.0, 1.0, 1.0, 1.0 );
+ CGContextSetLineDash ( mrContext, 0, dashLengths, 2 );
+ CGContextSetLineWidth( mrContext, 2.0);
+ CGContextStrokePath ( mrContext );
+ }
+ else if ( nSalFlags & SAL_INVERT_50 )
+ {
+ CGContextSetBlendMode(mrContext, kCGBlendModeDifference);
+ Pattern50Fill();
+ }
+ else // just invert
+ {
+ CGContextSetBlendMode( mrContext, kCGBlendModeDifference );
+ CGContextSetRGBFillColor( mrContext, 1.0, 1.0, 1.0, 1.0 );
+ CGContextFillPath( mrContext );
+ }
+ const CGRect aRefreshRect = CGContextGetClipBoundingBox(mrContext);
+ CGContextRestoreGState( mrContext);
+ delete [] CGpoints;
+ RefreshRect( aRefreshRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalGraphics::drawEPS( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/,
+ void* /*pEpsData*/, sal_uLong /*nByteCount*/ )
+{
+ return sal_False;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+bool IosSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
+ const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp )
+{
+ // An image mask can't have a depth > 8 bits (should be 1 to 8 bits)
+ if( rAlphaBmp.GetBitCount() > 8 )
+ return false;
+
+ // are these two tests really necessary? (see vcl/unx/source/gdi/salgdi2.cxx)
+ // horizontal/vertical mirroring not implemented yet
+ if( rTR.mnDestWidth < 0 || rTR.mnDestHeight < 0 )
+ return false;
+
+ const IosSalBitmap& rSrcSalBmp = static_cast<const IosSalBitmap&>(rSrcBitmap);
+ const IosSalBitmap& rMaskSalBmp = static_cast<const IosSalBitmap&>(rAlphaBmp);
+
+ CGImageRef xMaskedImage = rSrcSalBmp.CreateWithMask( rMaskSalBmp, rTR.mnSrcX, rTR.mnSrcY, rTR.mnSrcWidth, rTR.mnSrcHeight );
+ if( !xMaskedImage )
+ return false;
+
+ if ( CheckContext() )
+ {
+ const CGRect aDstRect = {{rTR.mnDestX, rTR.mnDestY}, {rTR.mnDestWidth, rTR.mnDestHeight}};
+ CGContextDrawImage( mrContext, aDstRect, xMaskedImage );
+ RefreshRect( aDstRect );
+ }
+
+ CGImageRelease(xMaskedImage);
+ return true;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+bool IosSalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
+ long nHeight, sal_uInt8 nTransparency )
+{
+ if( !CheckContext() )
+ return true;
+
+ // save the current state
+ CGContextSaveGState( mrContext );
+ CGContextSetAlpha( mrContext, (100-nTransparency) * (1.0/100) );
+
+ CGRect aRect = {{nX,nY},{nWidth-1,nHeight-1}};
+ if( IsPenVisible() )
+ {
+ aRect.origin.x += 0.5;
+ aRect.origin.y += 0.5;
+ }
+
+ CGContextBeginPath( mrContext );
+ CGContextAddRect( mrContext, aRect );
+ CGContextDrawPath( mrContext, kCGPathFill );
+
+ // restore state
+ CGContextRestoreGState(mrContext);
+ RefreshRect( aRect );
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetTextColor( SalColor nSalColor )
+{
+ mnColor = nSalColor;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel )
+{
+ (void)nFallbackLevel;
+
+ const double fPixelSize = (mfFakeDPIScale * CTFontGetSize( mpIosFontData->mpFontRef ));
+ pMetric->mnAscent = CTFontGetAscent( mpIosFontData->mpFontRef );
+ pMetric->mnDescent = -CTFontGetDescent( mpIosFontData->mpFontRef );
+ pMetric->mnExtLeading = CTFontGetLeading( mpIosFontData->mpFontRef );
+ pMetric->mnIntLeading = 0;
+ pMetric->mnWidth = static_cast<long>(mfFontStretch * fPixelSize + 0.5);
+}
+
+// -----------------------------------------------------------------------
+
+sal_uLong IosSalGraphics::GetKernPairs( sal_uLong, ImplKernPairData* )
+{
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static bool AddLocalTempFontDirs( void )
+{
+ static bool bFirst = true;
+ if( !bFirst )
+ return false;
+ bFirst = false;
+
+ // add private font files found in brand and base layer
+
+ rtl::OUString aBrandStr( RTL_CONSTASCII_USTRINGPARAM( "$BRAND_BASE_DIR" ) );
+ rtl_bootstrap_expandMacros( &aBrandStr.pData );
+ rtl::OUString aBrandSysPath;
+ OSL_VERIFY( osl_getSystemPathFromFileURL( aBrandStr.pData, &aBrandSysPath.pData ) == osl_File_E_None );
+
+ rtl::OStringBuffer aBrandFontDir( aBrandSysPath.getLength()*2 );
+ aBrandFontDir.append( rtl::OUStringToOString( aBrandSysPath, RTL_TEXTENCODING_UTF8 ) );
+ aBrandFontDir.append( "/share/fonts/truetype/" );
+
+ // iterate font files in that and call CTFontManagerRegisterFontsForURL for them?
+ bool bBrandSuccess = true;
+
+ rtl::OUString aBaseStr( RTL_CONSTASCII_USTRINGPARAM( "$OOO_BASE_DIR" ) );
+ rtl_bootstrap_expandMacros( &aBaseStr.pData );
+ rtl::OUString aBaseSysPath;
+ OSL_VERIFY( osl_getSystemPathFromFileURL( aBaseStr.pData, &aBaseSysPath.pData ) == osl_File_E_None );
+
+ rtl::OStringBuffer aBaseFontDir( aBaseSysPath.getLength()*2 );
+ aBaseFontDir.append( rtl::OUStringToOString( aBaseSysPath, RTL_TEXTENCODING_UTF8 ) );
+ aBaseFontDir.append( "/share/fonts/truetype/" );
+
+ // ditto
+ bool bBaseSuccess = true;
+
+ return bBrandSuccess && bBaseSuccess;
+}
+
+void IosSalGraphics::GetDevFontList( ImplDevFontList* pFontList )
+{
+ DBG_ASSERT( pFontList, "IosSalGraphics::GetDevFontList(NULL) !");
+
+ AddLocalTempFontDirs();
+
+ // The idea is to cache the list of system fonts once it has been generated.
+ // SalData seems to be a good place for this caching. However we have to
+ // carefully make the access to the font list thread-safe. If we register
+ // a font-change event handler to update the font list in case fonts have
+ // changed on the system we have to lock access to the list. The right
+ // way to do that is the solar mutex since GetDevFontList is protected
+ // through it as should be all event handlers
+
+ SalData* pSalData = GetSalData();
+ if (pSalData->mpFontList == NULL)
+ pSalData->mpFontList = new SystemFontList();
+
+ // Copy all ImplFontData objects contained in the SystemFontList
+ pSalData->mpFontList->AnnounceFonts( *pFontList );
+}
+
+// -----------------------------------------------------------------------
+
+bool IosSalGraphics::AddTempDevFont( ImplDevFontList*,
+ const String& rFontFileURL, const String& /*rFontName*/ )
+{
+ ::rtl::OUString aUSytemPath;
+ OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFontFileURL, aUSytemPath ) );
+
+ // TODO: Implement...
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+// callbacks from ATSUGlyphGetCubicPaths() fore GetGlyphOutline()
+struct GgoData { basegfx::B2DPolygon maPolygon; basegfx::B2DPolyPolygon* mpPolyPoly; };
+
+static OSStatus GgoLineToProc( const Float32Point* pPoint, void* pData )
+{
+ basegfx::B2DPolygon& rPolygon = static_cast<GgoData*>(pData)->maPolygon;
+ const basegfx::B2DPoint aB2DPoint( pPoint->x, pPoint->y );
+ rPolygon.append( aB2DPoint );
+ return noErr;
+}
+
+static OSStatus GgoCurveToProc( const Float32Point* pCP1, const Float32Point* pCP2,
+ const Float32Point* pPoint, void* pData )
+{
+ basegfx::B2DPolygon& rPolygon = static_cast<GgoData*>(pData)->maPolygon;
+ const sal_uInt32 nPointCount = rPolygon.count();
+ const basegfx::B2DPoint aB2DControlPoint1( pCP1->x, pCP1->y );
+ rPolygon.setNextControlPoint( nPointCount-1, aB2DControlPoint1 );
+ const basegfx::B2DPoint aB2DEndPoint( pPoint->x, pPoint->y );
+ rPolygon.append( aB2DEndPoint );
+ const basegfx::B2DPoint aB2DControlPoint2( pCP2->x, pCP2->y );
+ rPolygon.setPrevControlPoint( nPointCount, aB2DControlPoint2 );
+ return noErr;
+}
+
+static OSStatus GgoClosePathProc( void* pData )
+{
+ GgoData* pGgoData = static_cast<GgoData*>(pData);
+ basegfx::B2DPolygon& rPolygon = pGgoData->maPolygon;
+ if( rPolygon.count() > 0 )
+ pGgoData->mpPolyPoly->append( rPolygon );
+ rPolygon.clear();
+ return noErr;
+}
+
+static OSStatus GgoMoveToProc( const Float32Point* pPoint, void* pData )
+{
+ GgoClosePathProc( pData );
+ OSStatus eStatus = GgoLineToProc( pPoint, pData );
+ return eStatus;
+}
+
+sal_Bool IosSalGraphics::GetGlyphOutline( sal_GlyphId nGlyphId, basegfx::B2DPolyPolygon& rPolyPoly )
+{
+ GgoData aGgoData;
+ aGgoData.mpPolyPoly = &rPolyPoly;
+ rPolyPoly.clear();
+
+#if 0
+ ATSUStyle rATSUStyle = maATSUStyle; // TODO: handle glyph fallback when CWS pdffix02 is integrated
+ GlyphID aGlyphId = nGlyphId & GF_IDXMASK;
+ OSStatus eGgoStatus = noErr;
+ OSStatus eStatus = ATSUGlyphGetCubicPaths( rATSUStyle, aGlyphId,
+ GgoMoveToProc, GgoLineToProc, GgoCurveToProc, GgoClosePathProc,
+ &aGgoData, &eGgoStatus );
+ if( (eStatus != noErr) ) // TODO: why is (eGgoStatus!=noErr) when curves are involved?
+ return false;
+
+ GgoClosePathProc( &aGgoData );
+#endif
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+long IosSalGraphics::GetGraphicsWidth() const
+{
+ long w = 0;
+ if( mrContext && (mbWindow || mbVirDev) )
+ {
+ w = mnWidth;
+ }
+
+ if( w == 0 )
+ {
+ if( mbWindow && mpFrame )
+ w = mpFrame->maGeometry.nWidth;
+ }
+
+ return w;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphId, Rectangle& rRect )
+{
+#if 0
+ ATSUStyle rATSUStyle = maATSUStyle; // TODO: handle glyph fallback
+ GlyphID aGlyphId = nGlyphId & GF_IDXMASK;
+ ATSGlyphScreenMetrics aGlyphMetrics;
+ OSStatus eStatus = ATSUGlyphGetScreenMetrics( rATSUStyle,
+ 1, &aGlyphId, 0, FALSE, !mbNonAntialiasedText, &aGlyphMetrics );
+ if( eStatus != noErr )
+ return false;
+
+ const long nMinX = (long)(+aGlyphMetrics.topLeft.x - 0.5);
+ const long nMaxX = (long)(aGlyphMetrics.width + 0.5) + nMinX;
+ const long nMinY = (long)(-aGlyphMetrics.topLeft.y - 0.5);
+ const long nMaxY = (long)(aGlyphMetrics.height + 0.5) + nMinY;
+ rRect = Rectangle( nMinX, nMinY, nMaxX, nMaxY );
+#else
+ rRect = Rectangle( );
+#endif
+ return true;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::GetDevFontSubstList( OutputDevice* )
+{
+ // nothing to do since there are no device-specific fonts on Ios
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt16 IosSalGraphics::SetFont( ImplFontSelectData* pReqFont, int /*nFallbackLevel*/ )
+{
+ if( !pReqFont )
+ {
+ [mpAttributes removeAllObjects];
+ mpIosFontData = NULL;
+ return 0;
+ }
+
+ // store the requested device font entry
+ const ImplIosFontData* pIosFont = static_cast<const ImplIosFontData*>( pReqFont->mpFontData );
+ mpIosFontData = pIosFont;
+
+ // enable bold-emulation if needed
+ Boolean bFakeBold = FALSE;
+ if( (pReqFont->GetWeight() >= WEIGHT_BOLD)
+ && (pIosFont->GetWeight() < WEIGHT_SEMIBOLD) )
+ bFakeBold = TRUE;
+ // enable italic-emulation if needed
+ Boolean bFakeItalic = FALSE;
+ if( ((pReqFont->GetSlant() == ITALIC_NORMAL) || (pReqFont->GetSlant() == ITALIC_OBLIQUE))
+ && !((pIosFont->GetSlant() == ITALIC_NORMAL) || (pIosFont->GetSlant() == ITALIC_OBLIQUE)) )
+ bFakeItalic = TRUE;
+
+#if 0
+ // enable/disable antialiased text
+ mbNonAntialiasedText = pReqFont->mbNonAntialiased;
+ UInt32 nStyleRenderingOptions = kATSStyleNoOptions;
+ if( pReqFont->mbNonAntialiased )
+ nStyleRenderingOptions |= kATSStyleNoAntiAliasing;
+
+ // set horizontal/vertical mode
+ ATSUVerticalCharacterType aVerticalCharacterType = kATSUStronglyHorizontal;
+ if( pReqFont->mbVertical )
+ aVerticalCharacterType = kATSUStronglyVertical;
+
+ // prepare ATS-fontid as type matching to the kATSUFontTag request
+ ATSUFontID nFontID = static_cast<ATSUFontID>(pIosFont->GetFontId());
+
+ // update ATSU style attributes with requested font parameters
+ // TODO: no need to set styles which are already defaulted
+
+ const ATSUAttributeTag aTag[] =
+ {
+ kATSUFontTag,
+ kATSUSizeTag,
+ kATSUQDBoldfaceTag,
+ kATSUQDItalicTag,
+ kATSUStyleRenderingOptionsTag,
+ kATSUVerticalCharacterTag
+ };
+
+ const ByteCount aValueSize[] =
+ {
+ sizeof(ATSUFontID),
+ sizeof(fFixedSize),
+ sizeof(bFakeBold),
+ sizeof(bFakeItalic),
+ sizeof(nStyleRenderingOptions),
+ sizeof(aVerticalCharacterType)
+ };
+
+ const ATSUAttributeValuePtr aValue[] =
+ {
+ &nFontID,
+ &fFixedSize,
+ &bFakeBold,
+ &bFakeItalic,
+ &nStyleRenderingOptions,
+ &aVerticalCharacterType
+ };
+
+ static const int nTagCount = sizeof(aTag) / sizeof(*aTag);
+ OSStatus eStatus = ATSUSetAttributes( maATSUStyle, nTagCount,
+ aTag, aValueSize, aValue );
+ // reset ATSUstyle if there was an error
+ if( eStatus != noErr )
+ {
+ DBG_WARNING( "IosSalGraphics::SetFont() : Could not set font attributes!\n");
+ ATSUClearStyle( maATSUStyle );
+ mpIosFontData = NULL;
+ return 0;
+ }
+
+ // prepare font stretching
+ const ATSUAttributeTag aMatrixTag = kATSUFontMatrixTag;
+ if( (pReqFont->mnWidth == 0) || (pReqFont->mnWidth == pReqFont->mnHeight) )
+ {
+ mfFontStretch = 1.0;
+ ATSUClearAttributes( maATSUStyle, 1, &aMatrixTag );
+ }
+ else
+ {
+ mfFontStretch = (float)pReqFont->mnWidth / pReqFont->mnHeight;
+ CGAffineTransform aMatrix = CGAffineTransformMakeScale( mfFontStretch, 1.0F );
+ const ATSUAttributeValuePtr aAttr = &aMatrix;
+ const ByteCount aMatrixBytes = sizeof(aMatrix);
+ eStatus = ATSUSetAttributes( maATSUStyle, 1, &aMatrixTag, &aMatrixBytes, &aAttr );
+ DBG_ASSERT( (eStatus==noErr), "IosSalGraphics::SetFont() : Could not set font matrix\n");
+ }
+
+ // prepare font rotation
+ mnRotation = pReqFont->mnOrientation;
+
+#if OSL_DEBUG_LEVEL > 3
+ fprintf( stderr, "SetFont to (\"%s\", \"%s\", fontid=%d) for (\"%s\" \"%s\" weight=%d, slant=%d size=%dx%d orientation=%d)\n",
+ ::rtl::OUStringToOString( pIosFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ).getStr(),
+ ::rtl::OUStringToOString( pIosFont->GetStyleName(), RTL_TEXTENCODING_UTF8 ).getStr(),
+ (int)nFontID,
+ ::rtl::OUStringToOString( pReqFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ).getStr(),
+ ::rtl::OUStringToOString( pReqFont->GetStyleName(), RTL_TEXTENCODING_UTF8 ).getStr(),
+ pReqFont->GetWeight(),
+ pReqFont->GetSlant(),
+ pReqFont->mnHeight,
+ pReqFont->mnWidth,
+ pReqFont->mnOrientation);
+#endif
+
+#endif
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+const ImplFontCharMap* IosSalGraphics::GetImplFontCharMap() const
+{
+ if( !mpIosFontData )
+ return ImplFontCharMap::GetDefaultMap();
+
+ return mpIosFontData->GetImplFontCharMap();
+}
+
+bool IosSalGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
+{
+ if( !mpIosFontData )
+ return false;
+
+ return mpIosFontData->GetImplFontCapabilities(rFontCapabilities);
+}
+
+// -----------------------------------------------------------------------
+
+// fake a SFNT font directory entry for a font table
+// see http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html#Directory
+static void FakeDirEntry( FourCharCode eFCC, ByteCount nOfs, ByteCount nLen,
+ const unsigned char* /*pData*/, unsigned char*& rpDest )
+{
+ // write entry tag
+ rpDest[ 0] = (char)(eFCC >> 24);
+ rpDest[ 1] = (char)(eFCC >> 16);
+ rpDest[ 2] = (char)(eFCC >> 8);
+ rpDest[ 3] = (char)(eFCC >> 0);
+ // TODO: get entry checksum and write it
+ // not too important since the subsetter doesn't care currently
+ // for( pData+nOfs ... pData+nOfs+nLen )
+ // write entry offset
+ rpDest[ 8] = (char)(nOfs >> 24);
+ rpDest[ 9] = (char)(nOfs >> 16);
+ rpDest[10] = (char)(nOfs >> 8);
+ rpDest[11] = (char)(nOfs >> 0);
+ // write entry length
+ rpDest[12] = (char)(nLen >> 24);
+ rpDest[13] = (char)(nLen >> 16);
+ rpDest[14] = (char)(nLen >> 8);
+ rpDest[15] = (char)(nLen >> 0);
+ // advance to next entry
+ rpDest += 16;
+}
+
+static bool GetRawFontData( const ImplFontData* pFontData,
+ ByteVector& rBuffer, bool* pJustCFF )
+{
+ const ImplIosFontData* pIosFont = static_cast<const ImplIosFontData*>(pFontData);
+
+#if 0
+ const ATSUFontID nFontId = static_cast<ATSUFontID>(pIosFont->GetFontId());
+ ATSFontRef rFont = FMGetATSFontRefFromFont( nFontId );
+
+ ByteCount nCffLen = 0;
+ OSStatus eStatus = ATSFontGetTable( rFont, GetTag("CFF "), 0, 0, NULL, &nCffLen);
+ if( pJustCFF != NULL )
+ {
+ *pJustCFF = (eStatus == noErr) && (nCffLen > 0);
+ if( *pJustCFF )
+ {
+ rBuffer.resize( nCffLen );
+ eStatus = ATSFontGetTable( rFont, GetTag("CFF "), 0, nCffLen, (void*)&rBuffer[0], &nCffLen);
+ if( (eStatus != noErr) || (nCffLen <= 0) )
+ return false;
+ return true;
+ }
+ }
+
+ // get font table availability and size in bytes
+ ByteCount nHeadLen = 0;
+ eStatus = ATSFontGetTable( rFont, GetTag("head"), 0, 0, NULL, &nHeadLen);
+ if( (eStatus != noErr) || (nHeadLen <= 0) )
+ return false;
+ ByteCount nMaxpLen = 0;
+ eStatus = ATSFontGetTable( rFont, GetTag("maxp"), 0, 0, NULL, &nMaxpLen);
+ if( (eStatus != noErr) || (nMaxpLen <= 0) )
+ return false;
+ ByteCount nCmapLen = 0;
+ eStatus = ATSFontGetTable( rFont, GetTag("cmap"), 0, 0, NULL, &nCmapLen);
+ if( (eStatus != noErr) || (nCmapLen <= 0) )
+ return false;
+ ByteCount nNameLen = 0;
+ eStatus = ATSFontGetTable( rFont, GetTag("name"), 0, 0, NULL, &nNameLen);
+ if( (eStatus != noErr) || (nNameLen <= 0) )
+ return false;
+ ByteCount nHheaLen = 0;
+ eStatus = ATSFontGetTable( rFont, GetTag("hhea"), 0, 0, NULL, &nHheaLen);
+ if( (eStatus != noErr) || (nHheaLen <= 0) )
+ return false;
+ ByteCount nHmtxLen = 0;
+ eStatus = ATSFontGetTable( rFont, GetTag("hmtx"), 0, 0, NULL, &nHmtxLen);
+ if( (eStatus != noErr) || (nHmtxLen <= 0) )
+ return false;
+
+ // get the glyph outline tables
+ ByteCount nLocaLen = 0;
+ ByteCount nGlyfLen = 0;
+ if( (eStatus != noErr) || (nCffLen <= 0) )
+ {
+ eStatus = ATSFontGetTable( rFont, GetTag("loca"), 0, 0, NULL, &nLocaLen);
+ if( (eStatus != noErr) || (nLocaLen <= 0) )
+ return false;
+ eStatus = ATSFontGetTable( rFont, GetTag("glyf"), 0, 0, NULL, &nGlyfLen);
+ if( (eStatus != noErr) || (nGlyfLen <= 0) )
+ return false;
+ }
+
+ ByteCount nPrepLen=0, nCvtLen=0, nFpgmLen=0;
+ if( nGlyfLen ) // TODO: reduce PDF size by making hint subsetting optional
+ {
+ eStatus = ATSFontGetTable( rFont, GetTag("prep"), 0, 0, NULL, &nPrepLen);
+ eStatus = ATSFontGetTable( rFont, GetTag("cvt "), 0, 0, NULL, &nCvtLen);
+ eStatus = ATSFontGetTable( rFont, GetTag("fpgm"), 0, 0, NULL, &nFpgmLen);
+ }
+
+ // prepare a byte buffer for a fake font
+ int nTableCount = 7;
+ nTableCount += (nPrepLen>0) + (nCvtLen>0) + (nFpgmLen>0) + (nGlyfLen>0);
+ const ByteCount nFdirLen = 12 + 16*nTableCount;
+ ByteCount nTotalLen = nFdirLen;
+ nTotalLen += nHeadLen + nMaxpLen + nNameLen + nCmapLen;
+ if( nGlyfLen )
+ nTotalLen += nLocaLen + nGlyfLen;
+ else
+ nTotalLen += nCffLen;
+ nTotalLen += nHheaLen + nHmtxLen;
+ nTotalLen += nPrepLen + nCvtLen + nFpgmLen;
+ rBuffer.resize( nTotalLen );
+
+ // fake a SFNT font directory header
+ if( nTableCount < 16 )
+ {
+ int nLog2 = 0;
+ while( (nTableCount >> nLog2) > 1 ) ++nLog2;
+ rBuffer[ 1] = 1; // Win-TTF style scaler
+ rBuffer[ 5] = nTableCount; // table count
+ rBuffer[ 7] = nLog2*16; // searchRange
+ rBuffer[ 9] = nLog2; // entrySelector
+ rBuffer[11] = (nTableCount-nLog2)*16; // rangeShift
+ }
+
+ // get font table raw data and update the fake directory entries
+ ByteCount nOfs = nFdirLen;
+ unsigned char* pFakeEntry = &rBuffer[12];
+ eStatus = ATSFontGetTable( rFont, GetTag("cmap"), 0, nCmapLen, (void*)&rBuffer[nOfs], &nCmapLen);
+ FakeDirEntry( GetTag("cmap"), nOfs, nCmapLen, &rBuffer[0], pFakeEntry );
+ nOfs += nCmapLen;
+ if( nCvtLen ) {
+ eStatus = ATSFontGetTable( rFont, GetTag("cvt "), 0, nCvtLen, (void*)&rBuffer[nOfs], &nCvtLen);
+ FakeDirEntry( GetTag("cvt "), nOfs, nCvtLen, &rBuffer[0], pFakeEntry );
+ nOfs += nCvtLen;
+ }
+ if( nFpgmLen ) {
+ eStatus = ATSFontGetTable( rFont, GetTag("fpgm"), 0, nFpgmLen, (void*)&rBuffer[nOfs], &nFpgmLen);
+ FakeDirEntry( GetTag("fpgm"), nOfs, nFpgmLen, &rBuffer[0], pFakeEntry );
+ nOfs += nFpgmLen;
+ }
+ if( nCffLen ) {
+ eStatus = ATSFontGetTable( rFont, GetTag("CFF "), 0, nCffLen, (void*)&rBuffer[nOfs], &nCffLen);
+ FakeDirEntry( GetTag("CFF "), nOfs, nCffLen, &rBuffer[0], pFakeEntry );
+ nOfs += nGlyfLen;
+ } else {
+ eStatus = ATSFontGetTable( rFont, GetTag("glyf"), 0, nGlyfLen, (void*)&rBuffer[nOfs], &nGlyfLen);
+ FakeDirEntry( GetTag("glyf"), nOfs, nGlyfLen, &rBuffer[0], pFakeEntry );
+ nOfs += nGlyfLen;
+ eStatus = ATSFontGetTable( rFont, GetTag("loca"), 0, nLocaLen, (void*)&rBuffer[nOfs], &nLocaLen);
+ FakeDirEntry( GetTag("loca"), nOfs, nLocaLen, &rBuffer[0], pFakeEntry );
+ nOfs += nLocaLen;
+ }
+ eStatus = ATSFontGetTable( rFont, GetTag("head"), 0, nHeadLen, (void*)&rBuffer[nOfs], &nHeadLen);
+ FakeDirEntry( GetTag("head"), nOfs, nHeadLen, &rBuffer[0], pFakeEntry );
+ nOfs += nHeadLen;
+ eStatus = ATSFontGetTable( rFont, GetTag("hhea"), 0, nHheaLen, (void*)&rBuffer[nOfs], &nHheaLen);
+ FakeDirEntry( GetTag("hhea"), nOfs, nHheaLen, &rBuffer[0], pFakeEntry );
+ nOfs += nHheaLen;
+ eStatus = ATSFontGetTable( rFont, GetTag("hmtx"), 0, nHmtxLen, (void*)&rBuffer[nOfs], &nHmtxLen);
+ FakeDirEntry( GetTag("hmtx"), nOfs, nHmtxLen, &rBuffer[0], pFakeEntry );
+ nOfs += nHmtxLen;
+ eStatus = ATSFontGetTable( rFont, GetTag("maxp"), 0, nMaxpLen, (void*)&rBuffer[nOfs], &nMaxpLen);
+ FakeDirEntry( GetTag("maxp"), nOfs, nMaxpLen, &rBuffer[0], pFakeEntry );
+ nOfs += nMaxpLen;
+ eStatus = ATSFontGetTable( rFont, GetTag("name"), 0, nNameLen, (void*)&rBuffer[nOfs], &nNameLen);
+ FakeDirEntry( GetTag("name"), nOfs, nNameLen, &rBuffer[0], pFakeEntry );
+ nOfs += nNameLen;
+ if( nPrepLen ) {
+ eStatus = ATSFontGetTable( rFont, GetTag("prep"), 0, nPrepLen, (void*)&rBuffer[nOfs], &nPrepLen);
+ FakeDirEntry( GetTag("prep"), nOfs, nPrepLen, &rBuffer[0], pFakeEntry );
+ nOfs += nPrepLen;
+ }
+
+ DBG_ASSERT( (nOfs==nTotalLen), "IosSalGraphics::CreateFontSubset (nOfs!=nTotalLen)");
+#endif
+ return sal_True;
+}
+
+sal_Bool IosSalGraphics::CreateFontSubset( const rtl::OUString& rToFile,
+ const ImplFontData* pFontData, long* pGlyphIDs, sal_uInt8* pEncoding,
+ sal_Int32* pGlyphWidths, int nGlyphCount, FontSubsetInfo& rInfo )
+{
+ // TODO: move more of the functionality here into the generic subsetter code
+
+ // prepare the requested file name for writing the font-subset file
+ rtl::OUString aSysPath;
+ if( osl_File_E_None != osl_getSystemPathFromFileURL( rToFile.pData, &aSysPath.pData ) )
+ return sal_False;
+ const rtl_TextEncoding aThreadEncoding = osl_getThreadTextEncoding();
+ const ByteString aToFile( rtl::OUStringToOString( aSysPath, aThreadEncoding ) );
+
+ // get the raw-bytes from the font to be subset
+ ByteVector aBuffer;
+ bool bCffOnly = false;
+ if( !GetRawFontData( pFontData, aBuffer, &bCffOnly ) )
+ return sal_False;
+
+ // handle CFF-subsetting
+ if( bCffOnly )
+ {
+ // provide the raw-CFF data to the subsetter
+ ByteCount nCffLen = aBuffer.size();
+ rInfo.LoadFont( FontSubsetInfo::CFF_FONT, &aBuffer[0], nCffLen );
+
+ // NOTE: assuming that all glyphids requested on Ios are fully translated
+
+ // make the subsetter provide the requested subset
+ FILE* pOutFile = fopen( aToFile.GetBuffer(), "wb" );
+ bool bRC = rInfo.CreateFontSubset( FontSubsetInfo::TYPE1_PFB, pOutFile, NULL,
+ pGlyphIDs, pEncoding, nGlyphCount, pGlyphWidths );
+ fclose( pOutFile );
+ return bRC;
+ }
+
+ // TODO: modernize psprint's horrible fontsubset C-API
+ // this probably only makes sense after the switch to another SCM
+ // that can preserve change history after file renames
+
+ // prepare data for psprint's font subsetter
+ TrueTypeFont* pSftFont = NULL;
+ int nRC = ::OpenTTFontBuffer( (void*)&aBuffer[0], aBuffer.size(), 0, &pSftFont);
+ if( nRC != SF_OK )
+ return sal_False;
+
+ // get details about the subsetted font
+ TTGlobalFontInfo aTTInfo;
+ ::GetTTGlobalFontInfo( pSftFont, &aTTInfo );
+ rInfo.m_nFontType = FontSubsetInfo::SFNT_TTF;
+ rInfo.m_aPSName = String( aTTInfo.psname, RTL_TEXTENCODING_UTF8 );
+ rInfo.m_aFontBBox = Rectangle( Point( aTTInfo.xMin, aTTInfo.yMin ),
+ Point( aTTInfo.xMax, aTTInfo.yMax ) );
+ rInfo.m_nCapHeight = aTTInfo.yMax; // Well ...
+ rInfo.m_nAscent = +aTTInfo.winAscent;
+ rInfo.m_nDescent = -aTTInfo.winDescent;
+ // mac fonts usually do not have an OS2-table
+ // => get valid ascent/descent values from other tables
+ if( !rInfo.m_nAscent )
+ rInfo.m_nAscent = +aTTInfo.typoAscender;
+ if( !rInfo.m_nAscent )
+ rInfo.m_nAscent = +aTTInfo.ascender;
+ if( !rInfo.m_nDescent )
+ rInfo.m_nDescent = +aTTInfo.typoDescender;
+ if( !rInfo.m_nDescent )
+ rInfo.m_nDescent = -aTTInfo.descender;
+
+ // subset glyphs and get their properties
+ // take care that subset fonts require the NotDef glyph in pos 0
+ int nOrigCount = nGlyphCount;
+ sal_uInt16 aShortIDs[ 256 ];
+ sal_uInt8 aTempEncs[ 256 ];
+
+ int nNotDef = -1;
+ for( int i = 0; i < nGlyphCount; ++i )
+ {
+ aTempEncs[i] = pEncoding[i];
+ sal_uInt32 nGlyphIdx = pGlyphIDs[i] & GF_IDXMASK;
+ if( pGlyphIDs[i] & GF_ISCHAR )
+ {
+ bool bVertical = (pGlyphIDs[i] & GF_ROTMASK) != 0;
+ nGlyphIdx = ::MapChar( pSftFont, static_cast<sal_uInt16>(nGlyphIdx), bVertical );
+ if( nGlyphIdx == 0 && pFontData->IsSymbolFont() )
+ {
+ // #i12824# emulate symbol aliasing U+FXXX <-> U+0XXX
+ nGlyphIdx = pGlyphIDs[i] & GF_IDXMASK;
+ nGlyphIdx = (nGlyphIdx & 0xF000) ? (nGlyphIdx & 0x00FF) : (nGlyphIdx | 0xF000 );
+ nGlyphIdx = ::MapChar( pSftFont, static_cast<sal_uInt16>(nGlyphIdx), bVertical );
+ }
+ }
+ aShortIDs[i] = static_cast<sal_uInt16>( nGlyphIdx );
+ if( !nGlyphIdx )
+ if( nNotDef < 0 )
+ nNotDef = i; // first NotDef glyph found
+ }
+
+ if( nNotDef != 0 )
+ {
+ // add fake NotDef glyph if needed
+ if( nNotDef < 0 )
+ nNotDef = nGlyphCount++;
+
+ // NotDef glyph must be in pos 0 => swap glyphids
+ aShortIDs[ nNotDef ] = aShortIDs[0];
+ aTempEncs[ nNotDef ] = aTempEncs[0];
+ aShortIDs[0] = 0;
+ aTempEncs[0] = 0;
+ }
+ DBG_ASSERT( nGlyphCount < 257, "too many glyphs for subsetting" );
+
+ // TODO: where to get bVertical?
+ const bool bVertical = false;
+
+ // fill the pGlyphWidths array
+ // while making sure that the NotDef glyph is at index==0
+ TTSimpleGlyphMetrics* pGlyphMetrics =
+ ::GetTTSimpleGlyphMetrics( pSftFont, aShortIDs, nGlyphCount, bVertical );
+ if( !pGlyphMetrics )
+ return sal_False;
+ sal_uInt16 nNotDefAdv = pGlyphMetrics[0].adv;
+ pGlyphMetrics[0].adv = pGlyphMetrics[nNotDef].adv;
+ pGlyphMetrics[nNotDef].adv = nNotDefAdv;
+ for( int i = 0; i < nOrigCount; ++i )
+ pGlyphWidths[i] = pGlyphMetrics[i].adv;
+ free( pGlyphMetrics );
+
+ // write subset into destination file
+ nRC = ::CreateTTFromTTGlyphs( pSftFont, aToFile.GetBuffer(), aShortIDs,
+ aTempEncs, nGlyphCount, 0, NULL, 0 );
+ ::CloseTTFont(pSftFont);
+ return (nRC == SF_OK);
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::GetGlyphWidths( const ImplFontData* pFontData, bool bVertical,
+ Int32Vector& rGlyphWidths, Ucs2UIntMap& rUnicodeEnc )
+{
+ rGlyphWidths.clear();
+ rUnicodeEnc.clear();
+
+ if( pFontData->IsSubsettable() )
+ {
+ ByteVector aBuffer;
+ if( !GetRawFontData( pFontData, aBuffer, NULL ) )
+ return;
+
+ // TODO: modernize psprint's horrible fontsubset C-API
+ // this probably only makes sense after the switch to another SCM
+ // that can preserve change history after file renames
+
+ // use the font subsetter to get the widths
+ TrueTypeFont* pSftFont = NULL;
+ int nRC = ::OpenTTFontBuffer( (void*)&aBuffer[0], aBuffer.size(), 0, &pSftFont);
+ if( nRC != SF_OK )
+ return;
+
+ const int nGlyphCount = ::GetTTGlyphCount( pSftFont );
+ if( nGlyphCount > 0 )
+ {
+ // get glyph metrics
+ rGlyphWidths.resize(nGlyphCount);
+ std::vector<sal_uInt16> aGlyphIds(nGlyphCount);
+ for( int i = 0; i < nGlyphCount; i++ )
+ aGlyphIds[i] = static_cast<sal_uInt16>(i);
+ const TTSimpleGlyphMetrics* pGlyphMetrics = ::GetTTSimpleGlyphMetrics(
+ pSftFont, &aGlyphIds[0], nGlyphCount, bVertical );
+ if( pGlyphMetrics )
+ {
+ for( int i = 0; i < nGlyphCount; ++i )
+ rGlyphWidths[i] = pGlyphMetrics[i].adv;
+ free( (void*)pGlyphMetrics );
+ }
+
+ const ImplFontCharMap* pMap = mpIosFontData->GetImplFontCharMap();
+ DBG_ASSERT( pMap && pMap->GetCharCount(), "no charmap" );
+ pMap->AddReference(); // TODO: add and use RAII object instead
+
+ // get unicode<->glyph encoding
+ // TODO? avoid sft mapping by using the pMap itself
+ int nCharCount = pMap->GetCharCount();
+ sal_uInt32 nChar = pMap->GetFirstChar();
+ for(; --nCharCount >= 0; nChar = pMap->GetNextChar( nChar ) )
+ {
+ if( nChar > 0xFFFF ) // TODO: allow UTF-32 chars
+ break;
+ sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
+ sal_uInt32 nGlyph = ::MapChar( pSftFont, nUcsChar, bVertical );
+ if( nGlyph > 0 )
+ rUnicodeEnc[ nUcsChar ] = nGlyph;
+ }
+
+ pMap->DeReference(); // TODO: add and use RAII object instead
+ }
+
+ ::CloseTTFont( pSftFont );
+ }
+ else if( pFontData->IsEmbeddable() )
+ {
+ // get individual character widths
+ OSL_FAIL("not implemented for non-subsettable fonts!\n");
+ }
+}
+
+// -----------------------------------------------------------------------
+
+const Ucs2SIntMap* IosSalGraphics::GetFontEncodingVector(
+ const ImplFontData*, const Ucs2OStrMap** /*ppNonEncoded*/ )
+{
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+const void* IosSalGraphics::GetEmbedFontData( const ImplFontData*,
+ const sal_Ucs* /*pUnicodes*/,
+ sal_Int32* /*pWidths*/,
+ FontSubsetInfo&,
+ long* /*pDataLen*/ )
+{
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::FreeEmbedFontData( const void* pData, long /*nDataLen*/ )
+{
+ // TODO: implementing this only makes sense when the implementation of
+ // IosSalGraphics::GetEmbedFontData() returns non-NULL
+ (void)pData;
+ DBG_ASSERT( (pData!=NULL), "IosSalGraphics::FreeEmbedFontData() is not implemented\n");
+}
+
+// -----------------------------------------------------------------------
+
+SystemFontData IosSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
+{
+ SystemFontData aSysFontData;
+ OSStatus err;
+ aSysFontData.nSize = sizeof( SystemFontData );
+
+#if 0
+ // NOTE: Native ATSU font fallbacks are used, not the VCL fallbacks.
+ ATSUFontID fontId;
+ err = ATSUGetAttribute( maATSUStyle, kATSUFontTag, sizeof(fontId), &fontId, 0 );
+ if (err) fontId = 0;
+ aSysFontData.aATSUFontID = (void *) fontId;
+
+ Boolean bFbold;
+ err = ATSUGetAttribute( maATSUStyle, kATSUQDBoldfaceTag, sizeof(bFbold), &bFbold, 0 );
+ if (err) bFbold = FALSE;
+ aSysFontData.bFakeBold = (bool) bFbold;
+
+ Boolean bFItalic;
+ err = ATSUGetAttribute( maATSUStyle, kATSUQDItalicTag, sizeof(bFItalic), &bFItalic, 0 );
+ if (err) bFItalic = FALSE;
+ aSysFontData.bFakeItalic = (bool) bFItalic;
+
+ ATSUVerticalCharacterType aVerticalCharacterType;
+ err = ATSUGetAttribute( maATSUStyle, kATSUVerticalCharacterTag, sizeof(aVerticalCharacterType), &aVerticalCharacterType, 0 );
+ if (!err && aVerticalCharacterType == kATSUStronglyVertical) {
+ aSysFontData.bVerticalCharacterType = true;
+ } else {
+ aSysFontData.bVerticalCharacterType = false;
+ }
+
+ aSysFontData.bAntialias = !mbNonAntialiasedText;
+#endif
+ return aSysFontData;
+}
+
+// -----------------------------------------------------------------------
+
+SystemGraphicsData IosSalGraphics::GetGraphicsData() const
+{
+ SystemGraphicsData aRes;
+ aRes.nSize = sizeof(aRes);
+ aRes.rCGContext = mrContext;
+ return aRes;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalGraphics::SetXORMode( bool bSet, bool bInvertOnly )
+{
+ // return early if XOR mode remains unchanged
+ if( mbPrinter )
+ return;
+
+ if( ! bSet && mnXorMode == 2 )
+ {
+ CGContextSetBlendMode( mrContext, kCGBlendModeNormal );
+ mnXorMode = 0;
+ return;
+ }
+ else if( bSet && bInvertOnly && mnXorMode == 0)
+ {
+ CGContextSetBlendMode( mrContext, kCGBlendModeDifference );
+ mnXorMode = 2;
+ return;
+ }
+
+ if( (mpXorEmulation == NULL) && !bSet )
+ return;
+ if( (mpXorEmulation != NULL) && (bSet == mpXorEmulation->IsEnabled()) )
+ return;
+ if( !CheckContext() )
+ return;
+
+ // prepare XOR emulation
+ if( !mpXorEmulation )
+ {
+ mpXorEmulation = new XorEmulation();
+ mpXorEmulation->SetTarget( mnWidth, mnHeight, mnBitmapDepth, mrContext, mxLayer );
+ }
+
+ // change the XOR mode
+ if( bSet )
+ {
+ mpXorEmulation->Enable();
+ mrContext = mpXorEmulation->GetMaskContext();
+ mnXorMode = 1;
+ }
+ else
+ {
+ mpXorEmulation->UpdateTarget();
+ mpXorEmulation->Disable();
+ mrContext = mpXorEmulation->GetTargetContext();
+ mnXorMode = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+// apply the XOR mask to the target context if active and dirty
+void IosSalGraphics::ApplyXorContext()
+{
+ if( !mpXorEmulation )
+ return;
+ if( mpXorEmulation->UpdateTarget() )
+ RefreshRect( 0, 0, mnWidth, mnHeight ); // TODO: refresh minimal changerect
+}
+
+// ======================================================================
+
+XorEmulation::XorEmulation()
+: mxTargetLayer( NULL )
+, mxTargetContext( NULL )
+, mxMaskContext( NULL )
+, mxTempContext( NULL )
+, mpMaskBuffer( NULL )
+, mpTempBuffer( NULL )
+, mnBufferLongs( 0 )
+, mbIsEnabled( false )
+{}
+
+// ----------------------------------------------------------------------
+
+XorEmulation::~XorEmulation()
+{
+ Disable();
+ SetTarget( 0, 0, 0, NULL, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
+ CGContextRef xTargetContext, CGLayerRef xTargetLayer )
+{
+ // prepare to replace old mask+temp context
+ if( mxMaskContext )
+ {
+ // cleanup the mask context
+ CGContextRelease( mxMaskContext );
+ delete[] mpMaskBuffer;
+ mxMaskContext = NULL;
+ mpMaskBuffer = NULL;
+
+ // cleanup the temp context if needed
+ if( mxTempContext )
+ {
+ CGContextRelease( mxTempContext );
+ delete[] mpTempBuffer;
+ mxTempContext = NULL;
+ mpTempBuffer = NULL;
+ }
+ }
+
+ // return early if there is nothing more to do
+ if( !xTargetContext )
+ return;
+
+ // retarget drawing operations to the XOR mask
+ mxTargetLayer = xTargetLayer;
+ mxTargetContext = xTargetContext;
+
+ // prepare creation of matching CGBitmaps
+ CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
+ int nBitDepth = nTargetDepth;
+ if( !nBitDepth )
+ nBitDepth = 32;
+ int nBytesPerRow = (nBitDepth == 16) ? 2 : 4;
+ const size_t nBitsPerComponent = (nBitDepth == 16) ? 5 : 8;
+ if( nBitDepth <= 8 )
+ {
+ aCGColorSpace = GetSalData()->mxGraySpace;
+ aCGBmpInfo = kCGImageAlphaNone;
+ nBytesPerRow = 1;
+ }
+ nBytesPerRow *= nWidth;
+ mnBufferLongs = (nHeight * nBytesPerRow + sizeof(sal_uLong)-1) / sizeof(sal_uLong);
+
+ // create a XorMask context
+ mpMaskBuffer = new sal_uLong[ mnBufferLongs ];
+ mxMaskContext = ::CGBitmapContextCreate( mpMaskBuffer,
+ nWidth, nHeight, nBitsPerComponent, nBytesPerRow,
+ aCGColorSpace, aCGBmpInfo );
+ // reset the XOR mask to black
+ memset( mpMaskBuffer, 0, mnBufferLongs * sizeof(sal_uLong) );
+
+ // a bitmap context will be needed for manual XORing
+ // create one unless the target context is a bitmap context
+ if( nTargetDepth )
+ mpTempBuffer = (sal_uLong*)CGBitmapContextGetData( mxTargetContext );
+ if( !mpTempBuffer )
+ {
+ // create a bitmap context matching to the target context
+ mpTempBuffer = new sal_uLong[ mnBufferLongs ];
+ mxTempContext = ::CGBitmapContextCreate( mpTempBuffer,
+ nWidth, nHeight, nBitsPerComponent, nBytesPerRow,
+ aCGColorSpace, aCGBmpInfo );
+ }
+
+ // initialize XOR mask context for drawing
+ CGContextSetFillColorSpace( mxMaskContext, aCGColorSpace );
+ CGContextSetStrokeColorSpace( mxMaskContext, aCGColorSpace );
+ CGContextSetShouldAntialias( mxMaskContext, false );
+
+ // improve the XorMask's XOR emulation a litte
+ // NOTE: currently only enabled for monochrome contexts
+ if( aCGColorSpace == GetSalData()->mxGraySpace )
+ CGContextSetBlendMode( mxMaskContext, kCGBlendModeDifference );
+
+ // intialize the transformation matrix to the drawing target
+ const CGAffineTransform aCTM = CGContextGetCTM( xTargetContext );
+ CGContextConcatCTM( mxMaskContext, aCTM );
+ if( mxTempContext )
+ CGContextConcatCTM( mxTempContext, aCTM );
+
+ // initialize the default XorMask graphics state
+ CGContextSaveGState( mxMaskContext );
+}
+
+// ----------------------------------------------------------------------
+
+bool XorEmulation::UpdateTarget()
+{
+ if( !IsEnabled() )
+ return false;
+
+ // update the temp bitmap buffer if needed
+ if( mxTempContext )
+ CGContextDrawLayerAtPoint( mxTempContext, CGPointZero, mxTargetLayer );
+
+ // do a manual XOR with the XorMask
+ // this approach suffices for simple color manipulations
+ // and also the complex-clipping-XOR-trick used in metafiles
+ const sal_uLong* pSrc = mpMaskBuffer;
+ sal_uLong* pDst = mpTempBuffer;
+ for( int i = mnBufferLongs; --i >= 0;)
+ *(pDst++) ^= *(pSrc++);
+
+ // write back the XOR results to the target context
+ if( mxTempContext )
+ {
+ CGImageRef xXorImage = CGBitmapContextCreateImage( mxTempContext );
+ const int nWidth = (int)CGImageGetWidth( xXorImage );
+ const int nHeight = (int)CGImageGetHeight( xXorImage );
+ // TODO: update minimal changerect
+ const CGRect aFullRect = {{0,0},{nWidth,nHeight}};
+ CGContextDrawImage( mxTargetContext, aFullRect, xXorImage );
+ CGImageRelease( xXorImage );
+ }
+
+ // reset the XorMask to black again
+ // TODO: not needed for last update
+ memset( mpMaskBuffer, 0, mnBufferLongs * sizeof(sal_uLong) );
+
+ // TODO: return FALSE if target was not changed
+ return true;
+}
+
+// =======================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/ios/source/gdi/salvd.cxx b/vcl/ios/source/gdi/salvd.cxx
new file mode 100644
index 000000000000..16799310b1a1
--- /dev/null
+++ b/vcl/ios/source/gdi/salvd.cxx
@@ -0,0 +1,260 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include "vcl/svapp.hxx"
+#include "vcl/sysdata.hxx"
+
+#include "ios/salvd.h"
+#include "ios/salinst.h"
+#include "ios/salgdi.h"
+#include "ios/saldata.hxx"
+#include "ios/salframe.h"
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice* IosSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
+{
+ // #i92075# can be called first in a thread
+ SalData::ensureThreadAutoreleasePool();
+
+ return new IosSalVirtualDevice( static_cast< IosSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{
+ delete pDevice;
+}
+
+// =======================================================================
+
+IosSalVirtualDevice::IosSalVirtualDevice( IosSalGraphics* pGraphic, long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
+: mbGraphicsUsed( false )
+, mxBitmapContext( NULL )
+, mnBitmapDepth( 0 )
+, mxLayer( NULL )
+{
+ if( pGraphic && pData && pData->rCGContext )
+ {
+ // Create virtual device based on existing SystemGraphicsData
+ // We ignore nDx and nDY, as the desired size comes from the SystemGraphicsData
+ mbForeignContext = true; // the mxContext is from pData
+ mpGraphics = new IosSalGraphics( /*pGraphic*/ );
+ mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
+ }
+ else
+ {
+ // create empty new virtual device
+ mbForeignContext = false; // the mxContext is created within VCL
+ mpGraphics = new IosSalGraphics(); // never fails
+ mnBitmapDepth = nBitCount;
+
+ // inherit resolution from reference device
+ if( pGraphic )
+ {
+ IosSalFrame* pFrame = pGraphic->getGraphicsFrame();
+ if( pFrame && IosSalFrame::isAlive( pFrame ) )
+ {
+ mpGraphics->setGraphicsFrame( pFrame );
+ mpGraphics->copyResolution( *pGraphic );
+ }
+ }
+
+ if( nDX && nDY )
+ SetSize( nDX, nDY );
+
+ // NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IosSalVirtualDevice::~IosSalVirtualDevice()
+{
+ if( mpGraphics )
+ {
+ mpGraphics->SetVirDevGraphics( NULL, NULL );
+ delete mpGraphics;
+ mpGraphics = 0;
+ }
+ Destroy();
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalVirtualDevice::Destroy()
+{
+ if( mbForeignContext ) {
+ // Do not delete mxContext that we have received from outside VCL
+ mxLayer = NULL;
+ return;
+ }
+
+ if( mxLayer )
+ {
+ if( mpGraphics )
+ mpGraphics->SetVirDevGraphics( NULL, NULL );
+ CGLayerRelease( mxLayer );
+ mxLayer = NULL;
+ }
+
+ if( mxBitmapContext )
+ {
+ void* pRawData = CGBitmapContextGetData( mxBitmapContext );
+ rtl_freeMemory( pRawData );
+ CGContextRelease( mxBitmapContext );
+ mxBitmapContext = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* IosSalVirtualDevice::GetGraphics()
+{
+ if( mbGraphicsUsed || !mpGraphics )
+ return 0;
+
+ mbGraphicsUsed = true;
+ return mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ mbGraphicsUsed = false;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool IosSalVirtualDevice::SetSize( long nDX, long nDY )
+{
+ if( mbForeignContext )
+ {
+ // Do not delete/resize mxContext that we have received from outside VCL
+ return true;
+ }
+
+ if( mxLayer )
+ {
+ const CGSize aSize = CGLayerGetSize( mxLayer );
+ if( (nDX == aSize.width) && (nDY == aSize.height) )
+ {
+ // Yay, we do not have to do anything :)
+ return true;
+ }
+ }
+
+ Destroy();
+
+ // create a Quartz layer matching to the intended virdev usage
+ CGContextRef xCGContext = NULL;
+ if( mnBitmapDepth && (mnBitmapDepth < 16) )
+ {
+ mnBitmapDepth = 8; // TODO: are 1bit vdevs worth it?
+ const CGColorSpaceRef aCGColorSpace = GetSalData()->mxGraySpace;
+ const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNone;
+ const int nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;
+
+ void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
+ mxBitmapContext = ::CGBitmapContextCreate( pRawData, nDX, nDY,
+ mnBitmapDepth, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
+ xCGContext = mxBitmapContext;
+ }
+ else
+ {
+ // default to a UIView target context
+ IosSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
+ if( !pSalFrame && !GetSalData()->maFrames.empty() )
+ pSalFrame = *GetSalData()->maFrames.begin();
+ if( pSalFrame )
+ {
+#if 0 // No idea...
+ // #i91990#
+ UIWindow* pWindow = pSalFrame->getWindow();
+ if ( pWindow )
+ {
+ UIGraphicsContext* pUIContext = [UIGraphicsContext graphicsContextWithWindow: pWindow];
+ if( pUIContext )
+ xCGContext = reinterpret_cast<CGContextRef>([pUIContext graphicsPort]);
+ }
+ else
+#endif
+ {
+ // fall back to a bitmap context
+ mnBitmapDepth = 32;
+ const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
+ const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
+
+ void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
+ mxBitmapContext = ::CGBitmapContextCreate( pRawData, nDX, nDY,
+ 8, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
+ xCGContext = mxBitmapContext;
+ }
+ }
+ }
+
+ DBG_ASSERT( xCGContext, "no context" );
+
+ const CGSize aNewSize = { nDX, nDY };
+ mxLayer = CGLayerCreateWithContext( xCGContext, aNewSize, NULL );
+
+ if( mxLayer && mpGraphics )
+ {
+ // get the matching Quartz context
+ CGContextRef xDrawContext = CGLayerGetContext( mxLayer );
+ mpGraphics->SetVirDevGraphics( mxLayer, xDrawContext, mnBitmapDepth );
+ }
+
+ return (mxLayer != NULL);
+}
+
+// -----------------------------------------------------------------------
+
+void IosSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
+{
+ if( mxLayer )
+ {
+ const CGSize aSize = CGLayerGetSize( mxLayer );
+ rWidth = static_cast<long>(aSize.width);
+ rHeight = static_cast<long>(aSize.height);
+ }
+ else
+ {
+ rWidth = 0;
+ rHeight = 0;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 9d54803f7f3b..925ad70e199b 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1589,22 +1589,6 @@ sal_uInt16 Application::GetSystemWindowMode()
// -----------------------------------------------------------------------
-const String& Application::GetFontPath()
-{
- ImplSVData* pSVData = ImplGetSVData();
- if( !pSVData->maAppData.mpFontPath )
- {
- if( const char* pFontPath = ::getenv( "SAL_FONTPATH_PRIVATE" ) )
- pSVData->maAppData.mpFontPath = new String( String::CreateFromAscii( pFontPath ) );
- }
-
- if( pSVData->maAppData.mpFontPath )
- return *(pSVData->maAppData.mpFontPath);
- return ImplGetSVEmptyStr();
-}
-
-// -----------------------------------------------------------------------
-
UniqueItemId Application::CreateUniqueId()
{
ImplSVData* pSVData = ImplGetSVData();
diff --git a/vcl/source/gdi/alpha.cxx b/vcl/source/gdi/alpha.cxx
index 6107affaf4e9..7a256dd74b9c 100644
--- a/vcl/source/gdi/alpha.cxx
+++ b/vcl/source/gdi/alpha.cxx
@@ -108,25 +108,6 @@ Bitmap AlphaMask::GetBitmap() const
// -----------------------------------------------------------------------------
-sal_Bool AlphaMask::Crop( const Rectangle& rRectPixel )
-{
- return Bitmap::Crop( rRectPixel );
-}
-
-// -----------------------------------------------------------------------------
-
-sal_Bool AlphaMask::Expand( sal_uLong nDX, sal_uLong nDY, sal_uInt8* pInitTransparency )
-{
- Color aColor;
-
- if( pInitTransparency )
- aColor = Color( *pInitTransparency, *pInitTransparency, *pInitTransparency );
-
- return Bitmap::Expand( nDX, nDY, pInitTransparency ? &aColor : NULL );
-}
-
-// -----------------------------------------------------------------------------
-
sal_Bool AlphaMask::CopyPixel( const Rectangle& rRectDst, const Rectangle& rRectSrc,
const AlphaMask* pAlphaSrc )
{
@@ -245,79 +226,6 @@ sal_Bool AlphaMask::Erase( sal_uInt8 cTransparency )
// -----------------------------------------------------------------------------
-sal_Bool AlphaMask::Invert()
-{
- BitmapWriteAccess* pAcc = AcquireWriteAccess();
- sal_Bool bRet = sal_False;
-
- if( pAcc && pAcc->GetBitCount() == 8 )
- {
- BitmapColor aCol( 0 );
- const long nWidth = pAcc->Width(), nHeight = pAcc->Height();
- sal_uInt8* pMap = new sal_uInt8[ 256 ];
-
- for( long i = 0; i < 256; i++ )
- pMap[ i ] = ~(sal_uInt8) i;
-
- for( long nY = 0L; nY < nHeight; nY++ )
- {
- for( long nX = 0L; nX < nWidth; nX++ )
- {
- aCol.SetIndex( pMap[ pAcc->GetPixel( nY, nX ).GetIndex() ] );
- pAcc->SetPixel( nY, nX, aCol );
- }
- }
-
- delete[] pMap;
- bRet = sal_True;
- }
-
- if( pAcc )
- ReleaseAccess( pAcc );
-
- return bRet;
-}
-
-// -----------------------------------------------------------------------------
-
-sal_Bool AlphaMask::Mirror( sal_uLong nMirrorFlags )
-{
- return Bitmap::Mirror( nMirrorFlags );
-}
-
-// -----------------------------------------------------------------------------
-
-sal_Bool AlphaMask::Scale( const Size& rNewSize, sal_uLong nScaleFlag )
-{
- sal_Bool bRet = Bitmap::Scale( rNewSize, nScaleFlag );
-
- if( bRet && ( nScaleFlag == BMP_SCALE_INTERPOLATE ) )
- Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
-
- return bRet;
-}
-
-// -----------------------------------------------------------------------------
-
-sal_Bool AlphaMask::Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag )
-{
- sal_Bool bRet = Bitmap::Scale( rScaleX, rScaleY, nScaleFlag );
-
- if( bRet && ( nScaleFlag == BMP_SCALE_INTERPOLATE ) )
- Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
-
- return bRet;
-}
-
-// -----------------------------------------------------------------------------
-
-sal_Bool AlphaMask::Rotate( long nAngle10, sal_uInt8 cFillTransparency )
-{
- return Bitmap::Rotate( nAngle10, Color( cFillTransparency, cFillTransparency, cFillTransparency ) );
-}
-
-// -----------------------------------------------------------------------------
-
sal_Bool AlphaMask::Replace( const Bitmap& rMask, sal_uInt8 cReplaceTransparency )
{
BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
@@ -398,33 +306,6 @@ nTol
// -----------------------------------------------------------------------------
-sal_Bool AlphaMask::Replace( sal_uInt8* pSearchTransparencies, sal_uInt8* pReplaceTransparencies,
- sal_uLong nColorCount, sal_uLong* pTols )
-{
- Color* pSearchColors = new Color[ nColorCount ];
- Color* pReplaceColors = new Color[ nColorCount ];
- sal_Bool bRet;
-
- for( sal_uLong i = 0; i < nColorCount; i++ )
- {
- const sal_uInt8 cSearchTransparency = pSearchTransparencies[ i ];
- const sal_uInt8 cReplaceTransparency = pReplaceTransparencies[ i ];
-
- pSearchColors[ i ] = Color( cSearchTransparency, cSearchTransparency, cSearchTransparency );
- pReplaceColors[ i ] = Color( cReplaceTransparency, cReplaceTransparency, cReplaceTransparency );
- }
-
- bRet = Bitmap::Replace( pSearchColors, pReplaceColors, nColorCount, pTols ) &&
- Bitmap::Convert( BMP_CONVERSION_8BIT_GREYS );
-
- delete[] pSearchColors;
- delete[] pReplaceColors;
-
- return bRet;
-}
-
-// -----------------------------------------------------------------------------
-
void AlphaMask::ReleaseAccess( BitmapReadAccess* pAccess )
{
if( pAccess )
diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx
index c12eb1cabcf5..b857c0824975 100644
--- a/vcl/source/glyphs/glyphcache.cxx
+++ b/vcl/source/glyphs/glyphcache.cxx
@@ -175,25 +175,6 @@ GlyphCache& GlyphCache::GetInstance()
// -----------------------------------------------------------------------
-void GlyphCache::LoadFonts()
-{
- if( const char* pFontPath = ::getenv( "SAL_FONTPATH_PRIVATE" ) )
- AddFontPath( String::CreateFromAscii( pFontPath ) );
- const String& rFontPath = Application::GetFontPath();
- if( rFontPath.Len() > 0 )
- AddFontPath( rFontPath );
-}
-
-// -----------------------------------------------------------------------
-
-void GlyphCache::ClearFontPath()
-{
- if( mpFtManager )
- mpFtManager->ClearFontList();
-}
-
-// -----------------------------------------------------------------------
-
void GlyphCache::AddFontPath( const String& rFontPath )
{
if( !mpFtManager )
@@ -301,21 +282,6 @@ void GlyphCache::UncacheFont( ServerFont& rServerFont )
// -----------------------------------------------------------------------
-sal_uLong GlyphCache::CalcByteCount() const
-{
- sal_uLong nCacheSize = sizeof(*this);
- for( FontList::const_iterator it = maFontList.begin(); it != maFontList.end(); ++it )
- {
- const ServerFont* pSF = it->second;
- if( pSF )
- nCacheSize += pSF->GetByteCount();
- }
- // TODO: also account something for hashtable management
- return nCacheSize;
-}
-
-// -----------------------------------------------------------------------
-
void GlyphCache::GarbageCollect()
{
// when current GC font has been destroyed get another one
diff --git a/vcl/unx/generic/app/saldata.cxx b/vcl/unx/generic/app/saldata.cxx
index 6d502e8563df..d865bfbc55d4 100644
--- a/vcl/unx/generic/app/saldata.cxx
+++ b/vcl/unx/generic/app/saldata.cxx
@@ -266,8 +266,6 @@ int X11SalData::XIOErrorHdl( Display * )
X11SalData::X11SalData()
{
- bNoExceptions_ = !!getenv( "SAL_NOSEGV" );
-
pXLib_ = NULL;
m_pSalDisplay = NULL;
m_pInstance = NULL;
diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx
index 8156b86cab08..419dd6e631e2 100644
--- a/vcl/unx/generic/app/saldisp.cxx
+++ b/vcl/unx/generic/app/saldisp.cxx
@@ -92,7 +92,6 @@ Status XineramaGetInfo(Display*, int, XRectangle*, unsigned char*, int*);
#include <unx/salobj.h>
#include <unx/sm.hxx>
#include <unx/wmadaptor.hxx>
-#include <unx/dtint.hxx>
#include <osl/socket.h>
#include <poll.h>
@@ -505,7 +504,6 @@ SalDisplay::SalDisplay( Display *display ) :
mpInputMethod( NULL ),
pDisp_( display ),
m_pWMAdaptor( NULL ),
- m_pDtIntegrator( NULL ),
m_bUseRandRWrapper( true ),
m_nLastUserEventTime( CurrentTime )
{
@@ -547,8 +545,6 @@ void SalDisplay::doDestruct()
delete m_pWMAdaptor;
m_pWMAdaptor = NULL;
- delete m_pDtIntegrator;
- m_pDtIntegrator = NULL;
X11SalBitmap::ImplDestroyCache();
X11SalGraphics::releaseGlyphPeer();
@@ -863,21 +859,6 @@ void SalDisplay::Init()
// - - - - - - - - - - Window Manager - - - - - - - - - - -
m_pWMAdaptor = ::vcl_sal::WMAdaptor::createWMAdaptor( this );
- const char *pWM = getenv( "SAL_WM" );
- if( pWM )
- {
- long int nWM = 0;
- sscanf( pWM, "%li", &nWM );
- eWindowManager_ = SalWM(nWM);
- }
- else if( XInternAtom( pDisp_, "_SGI_TELL_WM", True ) )
- eWindowManager_ = FourDwm;
- else if( XInternAtom( pDisp_, "KWM_RUNNING", True ) )
- eWindowManager_ = mwm; // naja, eigentlich kwm ...
- else if( XInternAtom( pDisp_, "_OL_WIN_ATTR", True ) )
- eWindowManager_ = olwm;
- else if( m_pWMAdaptor->getWindowManagerName().EqualsAscii( "Dtwm" ) )
- eWindowManager_ = dtwm;
// - - - - - - - - - - Properties - - - - - - - - - - - - -
const char *pProperties = getenv( "SAL_PROPERTIES" );
@@ -933,29 +914,6 @@ void SalDisplay::Init()
if (VendorRelease ( GetDisplay() ) < 3600)
nProperties_ |= PROPERTY_BUG_FillPolygon_Tile;
}
-
- if( otherwm == eWindowManager_ )
- eWindowManager_ = olwm;
- }
- else
- if( GetServerVendor() == vendor_sco )
- {
- if( otherwm == eWindowManager_ ) eWindowManager_ = pmwm;
- }
- else
- if( GetServerVendor() == vendor_sgi )
- {
- if( GetVisual( m_nDefaultScreen ).GetDepth() > 8 && GetVisual( m_nDefaultScreen ).GetDepth() <= 16 )
- nProperties_ |= PROPERTY_BUG_XCopyArea_GXxor;
- nProperties_ |= PROPERTY_SUPPORT_XSetClipMask;
-
- if( otherwm == eWindowManager_ )
- eWindowManager_ = FourDwm;
- }
- else
- if( GetServerVendor() == vendor_hp )
- {
- if( otherwm == eWindowManager_ ) eWindowManager_ = dtwm;
}
else
if( GetServerVendor() == vendor_hummingbird )
@@ -964,23 +922,12 @@ void SalDisplay::Init()
nProperties_ |= PROPERTY_BUG_CopyArea_OnlySmallSlices;
}
- if( otherwm == eWindowManager_ )
- {
- if( !XInternAtom( pDisp_, "_MOTIF_WM_INFO", True ) )
- eWindowManager_ = olwm;
- // ???
- }
-
if( winmgr == eWindowManager_ )
{
nProperties_ &= ~PROPERTY_SUPPORT_WM_SetPos;
nProperties_ &= ~PROPERTY_SUPPORT_WM_Screen;
nProperties_ |= PROPERTY_FEATURE_Maximize;
}
- else if( dtwm == eWindowManager_ )
- {
- nProperties_ &= ~PROPERTY_SUPPORT_WM_ClientPos;
- }
else if( pmwm == eWindowManager_ )
{
nProperties_ &= ~PROPERTY_SUPPORT_WM_ClientPos;
@@ -989,9 +936,6 @@ void SalDisplay::Init()
InitXinerama();
- // initialize system settings update
- m_pDtIntegrator = DtIntegrator::CreateDtIntegrator();
-
#ifdef DBG_UTIL
PrintInfo();
#endif
@@ -1124,8 +1068,7 @@ void SalDisplay::ModifierMapping()
nMod1KeySym_ = sal_XModifier2Keysym( pDisp_, pXModMap, Mod1MapIndex );
// Auf Sun-Servern und SCO-Severn beruecksichtigt XLookupString
// nicht den NumLock Modifier.
- if( (GetServerVendor() == vendor_sun)
- || (GetServerVendor() == vendor_sco) )
+ if( GetServerVendor() == vendor_sun )
{
XLIB_KeyCode aNumLock = XKeysymToKeycode( pDisp_, XK_Num_Lock );
@@ -2594,22 +2537,14 @@ void SalDisplay::PrintInfo() const
{
fprintf( stderr, "\n" );
fprintf( stderr, "Environment\n" );
- fprintf( stderr, "\t$XENVIRONMENT \t\"%s\"\n",
- GetEnv( "XENVIRONMENT" ) );
fprintf( stderr, "\t$DISPLAY \t\"%s\"\n",
GetEnv( "DISPLAY" ) );
fprintf( stderr, "\t$SAL_VISUAL \t\"%s\"\n",
GetEnv( "SAL_VISUAL" ) );
- fprintf( stderr, "\t$SAL_FONTPATH \t\"%s\"\n",
- GetEnv( "SAL_FONTPATH" ) );
- fprintf( stderr, "\t$SAL_NOSEGV \t\"%s\"\n",
- GetEnv( "SAL_NOSEGV" ) );
fprintf( stderr, "\t$SAL_IGNOREXERRORS\t\"%s\"\n",
GetEnv( "SAL_IGNOREXERRORS" ) );
fprintf( stderr, "\t$SAL_PROPERTIES \t\"%s\"\n",
GetEnv( "SAL_PROPERTIES" ) );
- fprintf( stderr, "\t$SAL_WM \t\"%s\"\n",
- GetEnv( "SAL_WM" ) );
fprintf( stderr, "\t$SAL_SYNCHRONIZE \t\"%s\"\n",
GetEnv( "SAL_SYNCHRONIZE" ) );
diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx
index 81bc26cb3672..83a9e07a92d4 100644
--- a/vcl/unx/generic/app/salinst.cxx
+++ b/vcl/unx/generic/app/salinst.cxx
@@ -41,7 +41,6 @@
#include "unx/saldisp.hxx"
#include "unx/salinst.h"
#include "unx/salframe.h"
-#include "unx/dtint.hxx"
#include "unx/salprn.h"
#include "unx/sm.hxx"
diff --git a/vcl/unx/generic/app/salsys.cxx b/vcl/unx/generic/app/salsys.cxx
index c5f7174e3d4c..ab69cda23a47 100644
--- a/vcl/unx/generic/app/salsys.cxx
+++ b/vcl/unx/generic/app/salsys.cxx
@@ -30,7 +30,6 @@
#include "precompiled_vcl.hxx"
#include <unx/salunx.h>
-#include <unx/dtint.hxx>
#include <unx/saldata.hxx>
#include <unx/salinst.h>
#include <unx/saldisp.hxx>
diff --git a/vcl/unx/generic/app/wmadaptor.cxx b/vcl/unx/generic/app/wmadaptor.cxx
index 7ad584953069..b33349bfc595 100644
--- a/vcl/unx/generic/app/wmadaptor.cxx
+++ b/vcl/unx/generic/app/wmadaptor.cxx
@@ -73,7 +73,6 @@ public:
virtual void maximizeFrame( X11SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const;
virtual void shade( X11SalFrame* pFrame, bool bToShaded ) const;
virtual void setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pTransientFrame = NULL ) const;
- virtual bool supportsICCCMPos() const;
virtual void enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const;
virtual int handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const;
virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const;
@@ -184,7 +183,6 @@ static const WMAdaptorProtocol aAtomTab[] =
{ "SAL_EXTTEXTEVENT", WMAdaptor::SAL_EXTTEXTEVENT },
{ "SAL_GETTIMEEVENT", WMAdaptor::SAL_GETTIMEEVENT },
{ "VCL_SYSTEM_SETTINGS", WMAdaptor::VCL_SYSTEM_SETTINGS },
- { "DTWM_IS_RUNNING", WMAdaptor::DTWM_IS_RUNNING },
{ "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS },
{ "_XEMBED", WMAdaptor::XEMBED },
{ "_XEMBED_INFO", WMAdaptor::XEMBED_INFO },
@@ -268,84 +266,6 @@ WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) :
initAtoms();
getNetWmName(); // try to discover e.g. Sawfish
- // check for dtwm running
- if( m_aWMAtoms[ DTWM_IS_RUNNING ] )
- {
- if ( (XGetWindowProperty( m_pDisplay,
- m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultScreenNumber() ),
- m_aWMAtoms[ DTWM_IS_RUNNING ],
- 0, 1,
- False,
- XA_INTEGER,
- &aRealType,
- &nFormat,
- &nItems,
- &nBytesLeft,
- &pProperty) == 0
- && nItems)
- || (XGetWindowProperty( m_pDisplay,
- m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultScreenNumber() ),
- m_aWMAtoms[ DTWM_IS_RUNNING ],
- 0, 1,
- False,
- m_aWMAtoms[ DTWM_IS_RUNNING ],
- &aRealType,
- &nFormat,
- &nItems,
- &nBytesLeft,
- &pProperty) == 0
- && nItems))
- {
- if (*pProperty)
- {
- m_aWMName = String(RTL_CONSTASCII_USTRINGPARAM("Dtwm"));
- m_bTransientBehaviour = false;
- m_nWinGravity = CenterGravity;
- }
- XFree (pProperty);
- }
- else if( pProperty )
- {
- XFree( pProperty );
- pProperty = NULL;
- }
- }
- if( m_aWMName.Len() == 0 )
- {
- // check for window maker - needs different gravity
- Atom aWMakerRunning = XInternAtom( m_pDisplay, "_WINDOWMAKER_WM_PROTOCOLS", True );
- if( aWMakerRunning != None &&
- XGetWindowProperty( m_pDisplay,
- m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultScreenNumber() ),
- aWMakerRunning,
- 0, 32,
- False,
- XA_ATOM,
- &aRealType,
- &nFormat,
- &nItems,
- &nBytesLeft,
- &pProperty ) == 0 )
- {
- if( aRealType == XA_ATOM )
- m_aWMName = String( RTL_CONSTASCII_USTRINGPARAM("Windowmaker" ) );
- XFree( pProperty );
- m_nInitWinGravity = NorthWestGravity;
- }
- else if( pProperty )
- {
- XFree( pProperty );
- pProperty = NULL;
- }
- }
- if( m_aWMName.Len() == 0 )
- {
- if( XInternAtom( m_pDisplay, "_OL_WIN_ATTR", True ) )
- {
- m_aWMName = String( RTL_CONSTASCII_USTRINGPARAM( "Olwm" ) );
- m_nInitWinGravity = NorthWestGravity;
- }
- }
if( m_aWMName.Len() == 0 )
{
// check for ReflectionX wm (as it needs a workaround in Windows mode
@@ -1079,9 +999,6 @@ void WMAdaptor::setWMName( X11SalFrame* pFrame, const String& rWMName ) const
rtl::OString aTitle(rtl::OUStringToOString(rWMName,
osl_getThreadTextEncoding()));
- if( ! rWMName.Len() && m_aWMName.EqualsAscii( "Dtwm" ) )
- aTitle = rtl::OString(' ');
-
::rtl::OString aWMLocale;
rtl_Locale* pLocale = NULL;
osl_getProcessLocale( &pLocale );
@@ -1513,10 +1430,6 @@ void WMAdaptor::setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eTy
if( ! pReferenceFrame->bMapped_ )
pFrame->mbTransientForRoot = true;
}
- // #110333# in case no one ever sets a title prevent
- // the Dtwm taking the class instead
- if( m_aWMName.EqualsAscii( "Dtwm" ) )
- setWMName( pFrame, String() );
}
/*
@@ -1675,16 +1588,6 @@ void WMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVert
RevertToNone,
CurrentTime
);
- if( m_aWMName.EqualsAscii( "Dtwm" ) )
- {
- /*
- * Dtwm will only position correctly with center gravity
- * and in this case the request actually changes the frame
- * not the shell window
- */
- aTarget = Rectangle( Point( 0, 0 ), aScreenSize );
- aRestore.Move( -rGeom.nLeftDecoration, -rGeom.nTopDecoration );
- }
}
if( pFrame->maRestorePosSize.IsEmpty() )
@@ -1708,11 +1611,6 @@ void WMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVert
pFrame->maRestorePosSize = Rectangle();
pFrame->nWidth_ = rGeom.nWidth;
pFrame->nHeight_ = rGeom.nHeight;
- if( m_aWMName.EqualsAscii( "Dtwm" ) && pFrame->bMapped_ )
- {
- pFrame->maGeometry.nX += rGeom.nLeftDecoration;
- pFrame->maGeometry.nY += rGeom.nTopDecoration;
- }
}
}
@@ -1838,27 +1736,6 @@ void GnomeWMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool
}
/*
- * WMAdaptor::supportsICCCMPos
- */
-
-bool WMAdaptor::supportsICCCMPos() const
-{
- return
- m_aWMName.EqualsAscii( "Sawfish" )
- || m_aWMName.EqualsAscii( "Dtwm" );
-}
-
-/*
- * NetWMAdaptor::supportsICCCMPos
- */
-
-bool NetWMAdaptor::supportsICCCMPos() const
-{
- return true;
-}
-
-
-/*
* WMAdaptor::enableAlwaysOnTop
*/
void WMAdaptor::enableAlwaysOnTop( X11SalFrame*, bool /*bEnable*/ ) const
diff --git a/vcl/unx/generic/desktopdetect/desktopdetector.cxx b/vcl/unx/generic/desktopdetect/desktopdetector.cxx
index 77cabc229284..12ea4fcf7183 100644
--- a/vcl/unx/generic/desktopdetect/desktopdetector.cxx
+++ b/vcl/unx/generic/desktopdetect/desktopdetector.cxx
@@ -227,22 +227,6 @@ static bool is_kde4_desktop( Display* pDisplay )
return false;
}
-static bool is_cde_desktop( Display* pDisplay )
-{
- void* pLibrary = NULL;
-
- Atom nDtAtom = XInternAtom( pDisplay, "_DT_WM_READY", True );
- OUString aPathName( RTL_CONSTASCII_USTRINGPARAM( "file:///usr/dt/lib/libDtSvc.so" ) );
- if( nDtAtom && ( pLibrary = osl_loadModule( aPathName.pData, SAL_LOADMODULE_DEFAULT ) ) )
- {
- osl_unloadModule( (oslModule)pLibrary );
- return true;
- }
-
- return false;
-}
-
-
extern "C"
{
@@ -254,8 +238,6 @@ DESKTOP_DETECTOR_PUBLIC DesktopType get_desktop_environment()
{
OString aOver( pOverride );
- if ( aOver.equalsIgnoreAsciiCase( "cde" ) )
- return DESKTOP_CDE;
if ( aOver.equalsIgnoreAsciiCase( "kde4" ) )
return DESKTOP_KDE4;
if ( aOver.equalsIgnoreAsciiCase( "gnome" ) )
@@ -323,8 +305,6 @@ DESKTOP_DETECTOR_PUBLIC DesktopType get_desktop_environment()
ret = DESKTOP_KDE4;
else if ( is_gnome_desktop( pDisplay ) )
ret = DESKTOP_GNOME;
- else if ( is_cde_desktop( pDisplay ) )
- ret = DESKTOP_CDE;
else if ( is_kde_desktop( pDisplay ) )
ret = DESKTOP_KDE;
else
diff --git a/vcl/unx/generic/fontmanager/helper.cxx b/vcl/unx/generic/fontmanager/helper.cxx
index 4b0d327a9a03..673d8b0c5056 100644
--- a/vcl/unx/generic/fontmanager/helper.cxx
+++ b/vcl/unx/generic/fontmanager/helper.cxx
@@ -243,12 +243,6 @@ OUString psp::getFontPath()
aPathBuffer.appendAscii( "/user/fonts" );
}
}
- OString aEnvPath( getEnvironmentPath( "SAL_FONTPATH_PRIVATE" ) );
- if( aEnvPath.getLength() )
- {
- aPathBuffer.append( sal_Unicode(';') );
- aPathBuffer.append( OStringToOUString( aEnvPath, osl_getThreadTextEncoding() ) );
- }
aPath = aPathBuffer.makeStringAndClear();
#if OSL_DEBUG_LEVEL > 1
diff --git a/vcl/unx/generic/gdi/cdeint.cxx b/vcl/unx/generic/gdi/cdeint.cxx
deleted file mode 100644
index fc516099630f..000000000000
--- a/vcl/unx/generic/gdi/cdeint.cxx
+++ /dev/null
@@ -1,237 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#include <tools/stream.hxx>
-#include <tools/debug.hxx>
-
-#include <vcl/settings.hxx>
-
-#include <unx/salunx.h>
-#include <unx/saldisp.hxx>
-#include <unx/cdeint.hxx>
-
-CDEIntegrator::CDEIntegrator()
-{
- meType = DtCDE;
-}
-
-CDEIntegrator::~CDEIntegrator()
-{
-}
-
-static int getHexDigit( const char c )
-{
- if( c >= '0' && c <= '9' )
- return (int)(c-'0');
- else if( c >= 'a' && c <= 'f' )
- return (int)(c-'a'+10);
- else if( c >= 'A' && c <= 'F' )
- return (int)(c-'A'+10);
- return -1;
-}
-
-
-void CDEIntegrator::GetSystemLook( AllSettings& rSettings )
-{
- static Color aColors[ 8 ];
- static sal_Bool bRead = sal_False;
- static sal_Bool bValid = sal_False;
-
- if( ! bRead )
- {
- // get used palette from xrdb
- char **ppStringList = 0;
- int nStringCount;
- XTextProperty aTextProperty;
- aTextProperty.value = 0;
-
- static Atom nResMgrAtom = XInternAtom( mpDisplay, "RESOURCE_MANAGER", False );
-
- if( XGetTextProperty( mpDisplay,
- RootWindow( mpDisplay, 0 ),
- &aTextProperty,
- nResMgrAtom )
- && aTextProperty.value
- && XTextPropertyToStringList( &aTextProperty, &ppStringList, &nStringCount )
- )
- {
- // format of ColorPalette resource:
- // *n*ColorPalette: palettefile
-
- ByteString aLines;
- int i;
- for( i=0; i < nStringCount; i++ )
- aLines += ppStringList[i];
- for( i = aLines.GetTokenCount( '\n' )-1; i >= 0; i-- )
- {
- ByteString aLine = aLines.GetToken( i, '\n' );
- int nIndex = aLine.Search( "ColorPalette" );
- if( nIndex != STRING_NOTFOUND )
- {
- int nPos = nIndex;
-
- nIndex+=12;
- const char* pStr = aLine.GetBuffer() +nIndex;
- while( *pStr && isspace( *pStr ) && *pStr != ':' )
- {
- pStr++;
- nIndex++;
- }
- if( *pStr != ':' )
- continue;
- pStr++, nIndex++;
- for( ; *pStr && isspace( *pStr ); pStr++, nIndex++ )
- ;
- if( ! *pStr )
- continue;
- int nIndex2 = nIndex;
- for( ; *pStr && ! isspace( *pStr ); pStr++, nIndex2++ )
- ;
- ByteString aPaletteFile( aLine.Copy( nIndex, nIndex2 - nIndex ) );
- // extract number before ColorPalette;
- for( ; nPos >= 0 && aLine.GetChar( nPos ) != '*'; nPos-- )
- ;
- nPos--;
- for( ; nPos >= 0 && aLine.GetChar( nPos ) != '*'; nPos-- )
- ;
- int nNumber = aLine.Copy( ++nPos ).ToInt32();
-
- OSL_TRACE( "found palette %d in resource \"%s\"", nNumber, aLine.GetBuffer() );
-
- // found no documentation what this number actually means;
- // might be the screen number. 0 seems to be the right one
- // in most cases.
- if( nNumber )
- continue;
-
- OSL_TRACE( "Palette file is \"%s\".\n", aPaletteFile.GetBuffer() );
-
- String aPath( aHomeDir );
- aPath.AppendAscii( "/.dt/palettes/" );
- aPath += String( aPaletteFile, gsl_getSystemTextEncoding() );
-
- SvFileStream aStream( aPath, STREAM_READ );
- if( ! aStream.IsOpen() )
- {
- aPath = String::CreateFromAscii( "/usr/dt/palettes/" );
- aPath += String( aPaletteFile, gsl_getSystemTextEncoding() );
- aStream.Open( aPath, STREAM_READ );
- if( ! aStream.IsOpen() )
- continue;
- }
-
- ByteString aBuffer;
- for( nIndex = 0; nIndex < 8; nIndex++ )
- {
- aStream.ReadLine( aBuffer );
- // format is "#RRRRGGGGBBBB"
-
- OSL_TRACE( "\t\"%s\".\n", aBuffer.GetBuffer() );
-
- if( aBuffer.Len() )
- {
- const char* pArr = (const char*)aBuffer.GetBuffer()+1;
- aColors[nIndex] = Color(
- getHexDigit( pArr[1] )
- | ( getHexDigit( pArr[0] ) << 4 ),
- getHexDigit( pArr[5] )
- | ( getHexDigit( pArr[4] ) << 4 ),
- getHexDigit( pArr[9] )
- | ( getHexDigit( pArr[8] ) << 4 )
- );
-
- OSL_TRACE( "\t\t%lx\n", aColors[nIndex].GetColor() );
- }
- }
-
- bValid = sal_True;
- break;
- }
- }
- }
-
- if( ppStringList )
- XFreeStringList( ppStringList );
- if( aTextProperty.value )
- XFree( aTextProperty.value );
- }
-
-
- StyleSettings aStyleSettings = rSettings.GetStyleSettings();
- // #i48001# set a default blink rate
- aStyleSettings.SetCursorBlinkTime( 500 );
- if (bValid)
- {
- aStyleSettings.SetActiveColor( aColors[0] );
- aStyleSettings.SetActiveColor2( aColors[0] );
- aStyleSettings.SetActiveBorderColor( aColors[0] );
-
- aStyleSettings.SetDeactiveColor( aColors[0] );
- aStyleSettings.SetDeactiveColor2( aColors[0] );
- aStyleSettings.SetDeactiveBorderColor( aColors[0] );
-
- Color aActive =
- aColors[ 0 ].GetBlue() < 128 ||
- aColors[ 0 ].GetGreen() < 128 ||
- aColors[ 0 ].GetRed() < 128
- ? Color( COL_WHITE ) : Color( COL_BLACK );
- Color aDeactive =
- aColors[ 1 ].GetBlue() < 128 ||
- aColors[ 1 ].GetGreen() < 128 ||
- aColors[ 1 ].GetRed() < 128
- ? Color( COL_WHITE ) : Color( COL_BLACK );
- aStyleSettings.SetActiveTextColor( aActive );
- aStyleSettings.SetDeactiveTextColor( aDeactive );
-
- aStyleSettings.SetDialogTextColor( aDeactive );
- aStyleSettings.SetMenuTextColor( aDeactive );
- aStyleSettings.SetMenuBarTextColor( aDeactive );
- aStyleSettings.SetButtonTextColor( aDeactive );
- aStyleSettings.SetRadioCheckTextColor( aDeactive );
- aStyleSettings.SetGroupTextColor( aDeactive );
- aStyleSettings.SetLabelTextColor( aDeactive );
- aStyleSettings.SetInfoTextColor( aDeactive );
-
- aStyleSettings.Set3DColors( aColors[1] );
- aStyleSettings.SetFaceColor( aColors[1] );
- aStyleSettings.SetDialogColor( aColors[1] );
- aStyleSettings.SetMenuColor( aColors[1] );
- aStyleSettings.SetMenuBarColor( aColors[1] );
- aStyleSettings.SetCheckedColorSpecialCase( );
- }
- rSettings.SetStyleSettings( aStyleSettings );
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/dtint.cxx b/vcl/unx/generic/gdi/dtint.cxx
deleted file mode 100644
index df1826df90f5..000000000000
--- a/vcl/unx/generic/gdi/dtint.cxx
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dlfcn.h>
-
-#include "osl/file.h"
-#include "osl/process.h"
-#include "osl/security.h"
-
-#include "vcl/svapp.hxx"
-
-#include "unx/salunx.h"
-#include <X11/Xatom.h>
-#ifdef USE_CDE
-#include "unx/cdeint.hxx"
-#endif
-#include "unx/dtint.hxx"
-#include "unx/saldisp.hxx"
-#include "unx/saldata.hxx"
-#include "unx/wmadaptor.hxx"
-
-#include "dtsetenum.hxx"
-
-#include <set>
-#include <stdio.h>
-
-// NETBSD has no RTLD_GLOBAL
-#ifndef RTLD_GLOBAL
-#define DLOPEN_MODE (RTLD_LAZY)
-#else
-#define DLOPEN_MODE (RTLD_GLOBAL | RTLD_LAZY)
-#endif
-
-
-using namespace vcl_sal;
-
-using ::rtl::OUString;
-
-String DtIntegrator::aHomeDir;
-
-DtIntegrator::DtIntegrator() :
- meType( DtGeneric ),
- mnSystemLookCommandProcess( -1 )
-{
- mpSalDisplay = GetX11SalData()->GetDisplay();
- mpDisplay = mpSalDisplay->GetDisplay();
- OUString aDir;
- oslSecurity aCur = osl_getCurrentSecurity();
- if( aCur )
- {
- osl_getHomeDir( aCur, &aDir.pData );
- osl_freeSecurityHandle( aCur );
- OUString aSysDir;
- osl_getSystemPathFromFileURL( aDir.pData, &aSysDir.pData );
- aHomeDir = aSysDir;
- }
-}
-
-DtIntegrator::~DtIntegrator()
-{
-}
-
-DtIntegrator* DtIntegrator::CreateDtIntegrator()
-{
- /*
- * #i22061# override desktop detection
- * if environment variable OOO_FORCE_DESKTOP is set
- * to one of "cde" "kde" "gnome" then autodetection
- * is overridden.
- */
- static const char* pOverride = getenv( "OOO_FORCE_DESKTOP" );
- if( pOverride && *pOverride )
- {
- OString aOver( pOverride );
-
-#if USE_CDE
- if( aOver.equalsIgnoreAsciiCase( "cde" ) )
- return new CDEIntegrator();
-#endif
- if( aOver.equalsIgnoreAsciiCase( "none" ) )
- return new DtIntegrator();
- }
-
-#ifdef USE_CDE
- void* pLibrary = NULL;
-
- // check dt type
- // CDE
- SalDisplay* pSalDisplay = GetX11SalData()->GetDisplay();
- Display* pDisplay = pSalDisplay->GetDisplay();
- Atom nDtAtom = XInternAtom( pDisplay, "_DT_WM_READY", True );
- if( nDtAtom && ( pLibrary = dlopen( "/usr/dt/lib/libDtSvc.so", DLOPEN_MODE ) ) )
- {
- dlclose( pLibrary );
- return new CDEIntegrator();
- }
-#endif
-
- // default: generic implementation
- return new DtIntegrator();
-}
-
-void DtIntegrator::GetSystemLook( AllSettings& rSettings )
-{
- // #i48001# set a default blink rate
- StyleSettings aStyleSettings = rSettings.GetStyleSettings();
- aStyleSettings.SetCursorBlinkTime( 500 );
- rSettings.SetStyleSettings( aStyleSettings );
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx
index 4934ed7f83fa..235f08219c69 100644
--- a/vcl/unx/generic/gdi/salgdi3.cxx
+++ b/vcl/unx/generic/gdi/salgdi3.cxx
@@ -294,6 +294,11 @@ namespace
{
return nRotation != 0;
}
+
+ double toRadian(int nDegree10th)
+ {
+ return (3600 - (nDegree10th)) * M_PI / 1800.0;
+ }
}
void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
@@ -315,10 +320,10 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
switch (aGlyphId & GF_ROTMASK)
{
case GF_ROTL: // left
- glyph_extrarotation.push_back(900);
+ glyph_extrarotation.push_back(1);
break;
case GF_ROTR: // right
- glyph_extrarotation.push_back(-900);
+ glyph_extrarotation.push_back(-1);
break;
default:
glyph_extrarotation.push_back(0);
@@ -407,30 +412,64 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
std::vector<int>::const_iterator aNext = std::find_if(aI+1, aEnd, hasRotation);
+ size_t nStartIndex = std::distance(aStart, aI);
+ size_t nLen = std::distance(aI, aNext);
+
+ cairo_set_font_size(cr, nHeight);
+
cairo_matrix_init_identity(&m);
if (rFont.NeedsArtificialItalic())
m.xy = -m.xx * 0x6000L / 0x10000L;
if (rLayout.GetOrientation())
- cairo_matrix_rotate(&m, (3600 - rLayout.GetOrientation()) * M_PI / 1800.0);
+ cairo_matrix_rotate(&m, toRadian(rLayout.GetOrientation()));
cairo_matrix_scale(&m, nWidth, nHeight);
if (nGlyphRotation)
{
- cairo_matrix_rotate(&m, (3600 - nGlyphRotation) * M_PI / 1800.0);
+ cairo_matrix_rotate(&m, toRadian(nGlyphRotation*900));
+
+ cairo_matrix_t em_square;
+ cairo_matrix_init_identity(&em_square);
+ cairo_get_matrix(cr, &em_square);
+
+ FT_Face aFace = reinterpret_cast<FT_Face>(pFace);
+ cairo_matrix_scale(&em_square, aFace->units_per_EM,
+ aFace->units_per_EM);
+ cairo_set_matrix(cr, &em_square);
- cairo_font_extents_t extents;
- cairo_font_extents(cr, &extents);
- //gives the same positions as pre-cairo conversion, but I don't like them
- double xdiff = -extents.descent/(extents.height+extents.descent);
- cairo_matrix_translate(&m, xdiff, 1);
+ cairo_font_extents_t font_extents;
+ cairo_font_extents(cr, &font_extents);
+
+ cairo_matrix_init_identity(&em_square);
+ cairo_set_matrix(cr, &em_square);
+
+ //gives the same positions as pre-cairo conversion, but I don't
+ //like them
+ double xdiff = 0.0;
+ double ydiff = 0.0;
+ if (nGlyphRotation == 1)
+ {
+ ydiff = font_extents.ascent/nHeight;
+ xdiff = -font_extents.descent/nHeight;
+ }
+ else if (nGlyphRotation == -1)
+ {
+ cairo_text_extents_t text_extents;
+ cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
+ &text_extents);
+
+ xdiff = -text_extents.x_advance/nHeight;
+ //deliberate bug here for temp render-like-X11-impl,
+ //nWidth should be nHeight below
+ xdiff += font_extents.descent/nWidth;
+ }
+ cairo_matrix_translate(&m, xdiff, ydiff);
}
cairo_set_font_matrix(cr, &m);
- size_t nStartIndex = std::distance(aStart, aI);
- size_t nLen = std::distance(aI, aNext);
cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
#if OSL_DEBUG_LEVEL > 2
diff --git a/vcl/unx/generic/gdi/salprnpsp.cxx b/vcl/unx/generic/gdi/salprnpsp.cxx
index dbee65c589dc..3a3b406e53e4 100644
--- a/vcl/unx/generic/gdi/salprnpsp.cxx
+++ b/vcl/unx/generic/gdi/salprnpsp.cxx
@@ -1328,9 +1328,8 @@ sal_Bool PspSalPrinter::StartJob( const String* i_pFileName, const String& i_rJo
{
oslFileHandle pFile = NULL;
osl_openFile( aPDFFiles[i].maTmpURL.pData, &pFile, osl_File_OpenFlag_Read );
- if( pFile )
+ if (pFile && (osl_setFilePos(pFile, osl_Pos_Absolut, 0) == osl_File_E_None))
{
- osl_setFilePos( pFile, osl_Pos_Absolut, 0 );
std::vector< char > buffer( 0x10000, 0 );
// update job data with current page size
Size aPageSize( aPDFFiles[i].maParameters.maPageSize );
diff --git a/vcl/unx/generic/plugadapt/salplug.cxx b/vcl/unx/generic/plugadapt/salplug.cxx
index 8cadab79b0a7..e48ea3dc743d 100644
--- a/vcl/unx/generic/plugadapt/salplug.cxx
+++ b/vcl/unx/generic/plugadapt/salplug.cxx
@@ -276,7 +276,7 @@ void SalAbort( const XubString& rErrorText )
exit(-1);
}
-static const char * desktop_strings[] = { "none", "unknown", "GNOME", "KDE", "KDE4", "CDE" };
+static const char * desktop_strings[] = { "none", "unknown", "GNOME", "KDE", "KDE4" };
const OUString& SalGetDesktopEnvironment()
{
diff --git a/vcl/unx/generic/printergfx/printerjob.cxx b/vcl/unx/generic/printergfx/printerjob.cxx
index 9fb50947bcf4..b0db3def22c5 100644
--- a/vcl/unx/generic/printergfx/printerjob.cxx
+++ b/vcl/unx/generic/printergfx/printerjob.cxx
@@ -77,13 +77,14 @@ AppendPS (FILE* pDst, osl::File* pSrc, sal_uChar* pBuffer,
if ((pDst == NULL) || (pSrc == NULL))
return sal_False;
+ if (pSrc->setPos(osl_Pos_Absolut, 0) != osl::FileBase::E_None)
+ return sal_False;
+
if (nBlockSize == 0)
nBlockSize = nBLOCKSIZE;
if (pBuffer == NULL)
pBuffer = (sal_uChar*)alloca (nBlockSize);
- pSrc->setPos (osl_Pos_Absolut, 0);
-
sal_uInt64 nIn = 0;
sal_uInt64 nOut = 0;
do
diff --git a/vcl/unx/generic/printergfx/text_gfx.cxx b/vcl/unx/generic/printergfx/text_gfx.cxx
index 263e0b4c7995..3cad66ee948c 100644
--- a/vcl/unx/generic/printergfx/text_gfx.cxx
+++ b/vcl/unx/generic/printergfx/text_gfx.cxx
@@ -819,10 +819,14 @@ PrinterGfx::writeResources( osl::File* pFile, std::list< rtl::OString >& rSuppli
convertPfbToPfa (aFontFile, *pFile);
aFontFile.close ();
- pFile->setPos(osl_Pos_Current, -1);
char lastchar = '\n';
- sal_uInt64 uBytes(1);
- pFile->read((void *)(&lastchar), uBytes, uBytes);
+
+ if (pFile->setPos(osl_Pos_Current, -1) == osl::FileBase::E_None)
+ {
+ sal_uInt64 uBytes(1);
+ pFile->read((void *)(&lastchar), uBytes, uBytes);
+ }
+
if (lastchar != '\n')
WritePS (pFile, "\n");
}
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 2c1c94ae46c3..98d6c367a0e0 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -60,7 +60,6 @@
#include "unx/salgdi.h"
#include "unx/salframe.h"
#include "unx/soicon.hxx"
-#include "unx/dtint.hxx"
#include "unx/sm.hxx"
#include "unx/wmadaptor.hxx"
#include "unx/salprn.h"
@@ -980,7 +979,6 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon )
#endif
const int ourLargestIconSize = 48;
- bool bFoundIconSize = false;
int i;
for( i=0; i<nSizes; i++)
@@ -997,7 +995,6 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon )
&& pIconSize[i].max_width <= 2*ourLargestIconSize )
{
iconSize = pIconSize[i].max_width;
- bFoundIconSize = true;
}
iconSize = pIconSize[i].max_width;
@@ -1009,18 +1006,6 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon )
#endif
}
- if ( !bFoundIconSize )
- {
- // Unless someone has fixed olwm/olvwm, we have rejected
- // the max icon size from |XGetIconSizes()|. Provide a
- // better icon size default value, in case our window manager
- // is olwm/olvwm.
- const String& rWM( pDisplay_->getWMAdaptor()->getWindowManagerName() );
-
- if ( rWM.EqualsAscii( "Olwm" ) )
- iconSize = 48;
- }
-
XFree( pIconSize );
}
else
@@ -1718,7 +1703,6 @@ void X11SalFrame::SetWindowState( const SalFrameState *pState )
}
const Size& aScreenSize = pDisplay_->getDataForScreen( m_nScreen ).m_aSize;
- const WMAdaptor *pWM = GetDisplay()->getWMAdaptor();
if( bDoAdjust && aPosSize.GetWidth() <= aScreenSize.Width()
&& aPosSize.GetHeight() <= aScreenSize.Height() )
@@ -1752,17 +1736,7 @@ void X11SalFrame::SetWindowState( const SalFrameState *pState )
aPosSize.Move( 0, (long)aGeom.nTopDecoration - (long)aPosSize.Top() );
}
- // resize with new args
- if (pWM->supportsICCCMPos())
- {
- if( mpParent )
- aPosSize.Move( -mpParent->maGeometry.nX,
- -mpParent->maGeometry.nY );
- SetPosSize( aPosSize );
- bDefaultPosition_ = False;
- }
- else
- SetPosSize( 0, 0, aPosSize.GetWidth(), aPosSize.GetHeight(), SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
+ SetPosSize( 0, 0, aPosSize.GetWidth(), aPosSize.GetHeight(), SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
}
}
@@ -2676,13 +2650,9 @@ inline Color getColorFromLong( long nColor )
void X11SalFrame::UpdateSettings( AllSettings& rSettings )
{
-
- DtIntegrator* pIntegrator = GetDisplay()->getDtIntegrator();
-#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr, "DtIntegrator: %d\n", pIntegrator ? pIntegrator->GetDtType() : -1 );
-#endif
- if( pIntegrator )
- pIntegrator->GetSystemLook( rSettings );
+ StyleSettings aStyleSettings = rSettings.GetStyleSettings();
+ aStyleSettings.SetCursorBlinkTime( 500 );
+ rSettings.SetStyleSettings( aStyleSettings );
}
void X11SalFrame::CaptureMouse( sal_Bool bCapture )
@@ -4123,10 +4093,6 @@ long X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent )
}
else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) )
{
- bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" );
-
- if( ! bSession )
- {
if( this == s_pSaveYourselfFrame )
{
rtl::OString aExec(rtl::OUStringToOString(SessionManagerClient::getExecName(), osl_getThreadTextEncoding()));
@@ -4141,14 +4107,6 @@ long X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent )
else
// can only happen in race between WM and window closing
XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 );
- }
- else
- {
- // save open documents; would be good for non Dtwm, too,
- // but there is no real Shutdown message in the ancient
- // SM protocol; on Dtwm SaveYourself really means Shutdown, too.
- IceSalSession::handleOldX11SaveYourself( this );
- }
}
}
}
@@ -4372,22 +4330,6 @@ long X11SalFrame::Dispatch( XEvent *pEvent )
if( hPresentationWindow != None && GetShellWindow() == hPresentationWindow )
XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent, CurrentTime );
- /* For unknown reasons Dtwm does respect the input_hint
- * set to False, but not when mapping the window. So
- * emulate the correct behaviour and set the focus back
- * to where it most probably should have been.
- */
- if( (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) &&
- mpParent &&
- GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Dtwm" )
- )
- {
- XSetInputFocus( GetXDisplay(),
- mpParent->GetShellWindow(),
- RevertToParent,
- CurrentTime );
- bSetFocus = false;
- }
if( bSetFocus )
{
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 28b514148f50..d8f58fa79936 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -57,7 +57,7 @@
#include <stdio.h>
-#if QT_VERSION >= QT_VERSION_CHECK( 4, 8, 0 )
+#if QT_VERSION >= QT_VERSION_CHECK( 4, 8, 1 )
#define QT_UNIX_EVENT_LOOP_SUPPORT
#ifdef KDE_HAVE_GLIB
#define GLIB_EVENT_LOOP_SUPPORT