summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/aqua/inc/salgdi.h1
-rw-r--r--vcl/aqua/source/gdi/salnativewidgets.cxx16
-rw-r--r--vcl/inc/postgraphitestl.h9
-rw-r--r--vcl/inc/pregraphitestl.h30
-rw-r--r--vcl/inc/vcl/combobox.hxx4
-rw-r--r--vcl/inc/vcl/graphite_adaptors.hxx5
-rw-r--r--vcl/inc/vcl/graphite_cache.hxx4
-rw-r--r--vcl/inc/vcl/graphite_features.hxx3
-rw-r--r--vcl/inc/vcl/graphite_layout.hxx2
-rw-r--r--vcl/inc/vcl/ilstbox.hxx10
-rw-r--r--vcl/inc/vcl/lstbox.hxx4
-rw-r--r--vcl/inc/vcl/popupmenuwindow.hxx50
-rw-r--r--vcl/inc/vcl/ppdparser.hxx23
-rw-r--r--vcl/inc/vcl/printerinfomanager.hxx2
-rw-r--r--vcl/inc/vcl/tabctrl.hxx4
-rw-r--r--vcl/inc/vcl/tabdlg.hxx3
-rw-r--r--vcl/inc/vcl/vclevent.hxx24
-rw-r--r--vcl/inc/vcl/window.h3
-rw-r--r--vcl/inc/vcl/window.hxx9
-rw-r--r--vcl/prj/build.lst2
-rw-r--r--vcl/prj/d.lst1
-rw-r--r--vcl/source/app/vclevent.cxx23
-rw-r--r--vcl/source/control/combobox.cxx24
-rw-r--r--vcl/source/control/ilstbox.cxx27
-rw-r--r--vcl/source/control/lstbox.cxx21
-rw-r--r--vcl/source/control/tabctrl.cxx12
-rw-r--r--vcl/source/fontsubset/gsub.cxx13
-rw-r--r--vcl/source/fontsubset/sft.cxx20
-rw-r--r--vcl/source/gdi/outdev3.cxx2
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx1272
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx55
-rw-r--r--vcl/source/glyphs/gcach_ftyp.cxx13
-rw-r--r--vcl/source/glyphs/graphite_adaptors.cxx2
-rw-r--r--vcl/source/glyphs/graphite_cache.cxx2
-rw-r--r--vcl/source/glyphs/graphite_features.cxx6
-rw-r--r--vcl/source/glyphs/graphite_layout.cxx14
-rw-r--r--vcl/source/glyphs/graphite_textsrc.cxx10
-rw-r--r--vcl/source/glyphs/graphite_textsrc.hxx4
-rw-r--r--vcl/source/window/dlgctrl.cxx15
-rw-r--r--vcl/source/window/makefile.mk1
-rw-r--r--vcl/source/window/menu.cxx16
-rw-r--r--vcl/source/window/popupmenuwindow.cxx82
-rw-r--r--vcl/source/window/status.cxx1
-rw-r--r--vcl/source/window/tabdlg.cxx18
-rw-r--r--vcl/source/window/window.cxx32
-rw-r--r--vcl/unx/gtk/a11y/atkutil.cxx11
-rw-r--r--vcl/unx/gtk/a11y/atkwindow.cxx41
-rw-r--r--vcl/unx/gtk/a11y/atkwrapper.cxx54
-rw-r--r--vcl/unx/gtk/app/gtkinst.cxx5
-rw-r--r--vcl/unx/gtk/window/gtkframe.cxx2
-rw-r--r--vcl/unx/headless/svpprn.cxx2
-rw-r--r--vcl/unx/source/app/randrwrapper.cxx3
-rw-r--r--vcl/unx/source/dtrans/X11_dndcontext.cxx12
-rw-r--r--vcl/unx/source/dtrans/X11_dndcontext.hxx20
-rw-r--r--vcl/unx/source/dtrans/X11_selection.cxx192
-rw-r--r--vcl/unx/source/dtrans/X11_selection.hxx100
-rw-r--r--vcl/unx/source/dtrans/bmp.cxx2
-rw-r--r--vcl/unx/source/dtrans/bmp.hxx2
-rw-r--r--vcl/unx/source/gdi/salgdi.cxx18
-rw-r--r--vcl/unx/source/gdi/salprnpsp.cxx2
-rw-r--r--vcl/unx/source/printer/cupsmgr.cxx4
-rw-r--r--vcl/unx/source/printer/ppdparser.cxx440
-rw-r--r--vcl/unx/source/printer/printerinfomanager.cxx1
-rw-r--r--vcl/unx/source/printergfx/printerjob.cxx3
-rw-r--r--vcl/util/makefile.mk1
-rw-r--r--vcl/util/makefile2.pmk7
-rwxr-xr-x[-rw-r--r--]vcl/win/source/window/salframe.cxx5
67 files changed, 1917 insertions, 904 deletions
diff --git a/vcl/aqua/inc/salgdi.h b/vcl/aqua/inc/salgdi.h
index e835ac773a50..f557c4d2e79b 100644
--- a/vcl/aqua/inc/salgdi.h
+++ b/vcl/aqua/inc/salgdi.h
@@ -362,6 +362,7 @@ private:
void ApplyXorContext();
void Pattern50Fill();
UInt32 getState( ControlState nState );
+ UInt32 getTrackState( ControlState nState );
};
class XorEmulation
diff --git a/vcl/aqua/source/gdi/salnativewidgets.cxx b/vcl/aqua/source/gdi/salnativewidgets.cxx
index 754358823a93..1536299331cb 100644
--- a/vcl/aqua/source/gdi/salnativewidgets.cxx
+++ b/vcl/aqua/source/gdi/salnativewidgets.cxx
@@ -450,6 +450,15 @@ UInt32 AquaSalGraphics::getState( ControlState nState )
return kThemeStateActive;
}
+UInt32 AquaSalGraphics::getTrackState( ControlState nState )
+{
+ bool bDrawActive = mpFrame ? ([mpFrame->getWindow() isKeyWindow] ? true : false) : true;
+ if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive )
+ return kThemeTrackInactive;
+
+ return kThemeTrackActive;
+}
+
/*
* DrawNativeControl()
*
@@ -767,7 +776,10 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType,
aTrackInfo.attributes = kThemeTrackHorizontal;
if( Application::GetSettings().GetLayoutRTL() )
aTrackInfo.attributes |= kThemeTrackRightToLeft;
- aTrackInfo.enableState = (nState & CTRL_STATE_ENABLED) ? kThemeTrackActive : kThemeTrackInactive;
+ aTrackInfo.enableState = getTrackState( nState );
+ // the intro bitmap never gets key anyway; we want to draw that enabled
+ if( nType == CTRL_INTROPROGRESS )
+ aTrackInfo.enableState = kThemeTrackActive;
aTrackInfo.filler1 = 0;
aTrackInfo.trackInfo.progress.phase = static_cast<UInt8>(CFAbsoluteTimeGetCurrent()*10.0);
@@ -799,7 +811,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType,
aTrackDraw.attributes = kThemeTrackShowThumb;
if( nPart == PART_DRAW_BACKGROUND_HORZ )
aTrackDraw.attributes |= kThemeTrackHorizontal;
- aTrackDraw.enableState = kThemeTrackActive;
+ aTrackDraw.enableState = getTrackState( nState );
ScrollBarTrackInfo aScrollInfo;
aScrollInfo.viewsize = pScrollbarVal->mnVisibleSize;
diff --git a/vcl/inc/postgraphitestl.h b/vcl/inc/postgraphitestl.h
new file mode 100644
index 000000000000..736aa248b7ff
--- /dev/null
+++ b/vcl/inc/postgraphitestl.h
@@ -0,0 +1,9 @@
+#ifdef std_was_redefined_as_stlport
+// put things back the way they were
+# define std std_was_redefined_as_stlport
+# undef _STLP_OUTERMOST_HEADER_ID
+// force config to be re-read
+# undef _STLP_NOTHROW_INHERENTLY
+# undef _STLP_CONFIG_H
+# include <stddef.h>
+#endif
diff --git a/vcl/inc/pregraphitestl.h b/vcl/inc/pregraphitestl.h
new file mode 100644
index 000000000000..ece0af477113
--- /dev/null
+++ b/vcl/inc/pregraphitestl.h
@@ -0,0 +1,30 @@
+#if defined(GRAPHITEADAPTSTL) && defined(std)
+# include <ostream>
+# include <istream>
+# include <fstream>
+# include <iostream>
+# include <vector>
+# include <algorithm>
+# define std_was_redefined_as_stlport std
+# undef std
+# define _STLP_OUTERMOST_HEADER_ID 0xdeadbeaf
+# pragma GCC visibility push(default)
+# include _STLP_NATIVE_HEADER(exception_defines.h)
+# include _STLP_NATIVE_HEADER(limits)
+# include _STLP_NATIVE_HEADER(memory)
+# include _STLP_NATIVE_HEADER(exception)
+# include _STLP_NATIVE_HEADER(iosfwd)
+# include _STLP_NATIVE_HEADER(algorithm)
+# include _STLP_NATIVE_HEADER(string)
+# include _STLP_NATIVE_HEADER(streambuf)
+# include _STLP_NATIVE_HEADER(ios)
+# include _STLP_NATIVE_HEADER(locale)
+# include _STLP_NATIVE_HEADER(stdexcept)
+# include _STLP_NATIVE_HEADER(ostream)
+# include _STLP_NATIVE_HEADER(istream)
+# include _STLP_NATIVE_HEADER(iostream)
+# include _STLP_NATIVE_HEADER(vector)
+# pragma GCC visibility pop
+#endif
+//sil_std resolves to the std that Graphite was built with
+namespace sil_std = std;
diff --git a/vcl/inc/vcl/combobox.hxx b/vcl/inc/vcl/combobox.hxx
index d57d4b8a7372..cbceffaff6c0 100644
--- a/vcl/inc/vcl/combobox.hxx
+++ b/vcl/inc/vcl/combobox.hxx
@@ -192,8 +192,12 @@ public:
void* GetEntryData( USHORT nPos ) const;
void SetTopEntry( USHORT nPos );
+ void ShowProminentEntry( USHORT nPos );
USHORT GetTopEntry() const;
+ void SetProminentEntryType( ProminentEntry eType );
+ ProminentEntry GetProminentEntryType() const;
+
USHORT GetDisplayLineCount() const;
USHORT GetSelectEntryCount() const;
diff --git a/vcl/inc/vcl/graphite_adaptors.hxx b/vcl/inc/vcl/graphite_adaptors.hxx
index 41ffa00b0f8f..9a0a42c01ce0 100644
--- a/vcl/inc/vcl/graphite_adaptors.hxx
+++ b/vcl/inc/vcl/graphite_adaptors.hxx
@@ -58,10 +58,11 @@
#include "vcl/dllapi.h"
// Libraries
+#include "pregraphitestl.h"
#include <graphite/GrClient.h>
#include <graphite/Font.h>
#include <graphite/ITextSource.h>
-
+#include "postgraphitestl.h"
// Module type definitions and forward declarations.
//
@@ -121,7 +122,7 @@ public:
const grutils::GrFeatureParser * features() const { return mpFeatures; };
private:
- virtual void UniqueCacheInfo(std::wstring &, bool &, bool &);
+ virtual void UniqueCacheInfo(sil_std::wstring &, bool &, bool &);
FreetypeServerFont& mrFont;
FontProperties maFontProperties;
diff --git a/vcl/inc/vcl/graphite_cache.hxx b/vcl/inc/vcl/graphite_cache.hxx
index 5a537c5f1e48..73e3e2c9f1fe 100644
--- a/vcl/inc/vcl/graphite_cache.hxx
+++ b/vcl/inc/vcl/graphite_cache.hxx
@@ -58,10 +58,11 @@ public:
void clear();
#ifdef GRCACHE_REUSE_VECTORS
void setGlyphVectors(long nWidth, GraphiteLayout::Glyphs & vGlyphs, std::vector<int> vCharDxs,
- std::vector<int> & vChar2Base, std::vector<int> & vGlyph2Char)
+ std::vector<int> & vChar2Base, std::vector<int> & vGlyph2Char, float fScale)
{
clearVectors();
mnWidth = nWidth;
+ m_fontScale = fScale;
mvGlyphs.insert(mvGlyphs.begin(), vGlyphs.begin(), vGlyphs.end());
mvCharDxs.insert(mvCharDxs.begin(),vCharDxs.begin(),vCharDxs.end());
mvChar2BaseGlyph.insert(mvChar2BaseGlyph.begin(),vChar2Base.begin(),vChar2Base.end());
@@ -78,6 +79,7 @@ public:
const std::vector<int> & charDxs() const { return mvCharDxs; }
const std::vector<int> & char2BaseGlyph() const { return mvChar2BaseGlyph; }
const std::vector<int> & glyph2Char() const { return mvGlyph2Char; }
+ float & fontScale() { return m_fontScale; }
#endif
private:
rtl::OUString * m_rope;
diff --git a/vcl/inc/vcl/graphite_features.hxx b/vcl/inc/vcl/graphite_features.hxx
index 6cfe5dfca0fd..d3cfd99e0fe4 100644
--- a/vcl/inc/vcl/graphite_features.hxx
+++ b/vcl/inc/vcl/graphite_features.hxx
@@ -32,10 +32,11 @@
// Parse a string of features specified as ; separated pairs.
// e.g.
// 1001=1&2002=2&fav1=0
-
+#include "pregraphitestl.h"
#include <graphite/GrClient.h>
#include <graphite/Font.h>
#include <graphite/GrFeature.h>
+#include "postgraphitestl.h"
namespace grutils
{
diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx
index 2ec3bc4c2391..325f67e852ce 100644
--- a/vcl/inc/vcl/graphite_layout.hxx
+++ b/vcl/inc/vcl/graphite_layout.hxx
@@ -43,11 +43,13 @@
#include <vector>
#include <utility>
// Libraries
+#include "pregraphitestl.h"
#include <graphite/GrClient.h>
#include <graphite/Font.h>
#include <graphite/GrConstants.h>
#include <graphite/GrAppData.h>
#include <graphite/SegmentAux.h>
+#include "postgraphitestl.h"
// Platform
#include <vcl/sallayout.hxx>
#include <vcl/dllapi.h>
diff --git a/vcl/inc/vcl/ilstbox.hxx b/vcl/inc/vcl/ilstbox.hxx
index 81dd32ef2705..f38825028080 100644
--- a/vcl/inc/vcl/ilstbox.hxx
+++ b/vcl/inc/vcl/ilstbox.hxx
@@ -227,6 +227,7 @@ private:
long mnLeft; // Ausgabe ab Spalte
long mnBorder; // Abstand Rahmen - Text
long mnTextHeight; // Texthoehe
+ ProminentEntry meProminentType; // where is the "prominent" entry
USHORT mnSelectModifier; // Modifiers
@@ -309,6 +310,11 @@ public:
void SetTopEntry( USHORT nTop );
USHORT GetTopEntry() const { return mnTop; }
+ // ShowProminentEntry will set the entry correspoding to nEntryPos
+ // either at top or in the middle depending on the chosen style
+ void ShowProminentEntry( USHORT nEntryPos );
+ void SetProminentEntryType( ProminentEntry eType ) { meProminentType = eType; }
+ ProminentEntry GetProminentEntryType() const { return meProminentType; }
using Window::IsVisible;
BOOL IsVisible( USHORT nEntry ) const;
@@ -443,9 +449,13 @@ public:
void SetTopEntry( USHORT nTop ) { maLBWindow.SetTopEntry( nTop ); }
USHORT GetTopEntry() const { return maLBWindow.GetTopEntry(); }
+ void ShowProminentEntry( USHORT nPos ) { maLBWindow.ShowProminentEntry( nPos ); }
using Window::IsVisible;
BOOL IsVisible( USHORT nEntry ) const { return maLBWindow.IsVisible( nEntry ); }
+ void SetProminentEntryType( ProminentEntry eType ) { maLBWindow.SetProminentEntryType( eType ); }
+ ProminentEntry GetProminentEntryType() const { return maLBWindow.GetProminentEntryType(); }
+
long GetLeftIndent() const { return maLBWindow.GetLeftIndent(); }
void SetLeftIndent( USHORT n ) { maLBWindow.SetLeftIndent( n ); }
void ScrollHorz( short nDiff ) { maLBWindow.ScrollHorz( nDiff ); }
diff --git a/vcl/inc/vcl/lstbox.hxx b/vcl/inc/vcl/lstbox.hxx
index 0bf281798674..806ff9bb3e0f 100644
--- a/vcl/inc/vcl/lstbox.hxx
+++ b/vcl/inc/vcl/lstbox.hxx
@@ -168,9 +168,13 @@ public:
long GetEntryFlags( USHORT nPos ) const;
void SetTopEntry( USHORT nPos );
+ void ShowProminentEntry( USHORT nPos );
void SetTopEntryStr( const XubString& rStr );
USHORT GetTopEntry() const;
+ void SetProminentEntryType( ProminentEntry eType );
+ ProminentEntry GetProminentEntryType() const;
+
void SaveValue() { mnSaveValue = GetSelectEntryPos(); }
USHORT GetSavedValue() const { return mnSaveValue; }
diff --git a/vcl/inc/vcl/popupmenuwindow.hxx b/vcl/inc/vcl/popupmenuwindow.hxx
new file mode 100644
index 000000000000..af8d1f804598
--- /dev/null
+++ b/vcl/inc/vcl/popupmenuwindow.hxx
@@ -0,0 +1,50 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: floatwin.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __POPUPMENUWINDOW_HXX__
+#define __POPUPMENUWINDOW_HXX__
+
+#include "vcl/floatwin.hxx"
+
+class VCL_DLLPUBLIC PopupMenuFloatingWindow : public FloatingWindow
+{
+private:
+ struct ImplData;
+ ImplData* mpImplData;
+public:
+ PopupMenuFloatingWindow( Window* pParent, WinBits nStyle = (WB_SYSTEMFLOATWIN|WB_SYSTEMWINDOW|WB_NOBORDER) );
+ ~PopupMenuFloatingWindow();
+
+ sal_uInt16 GetMenuStackLevel() const;
+ void SetMenuStackLevel( sal_uInt16 nLevel );
+ bool IsPopupMenu() const;
+};
+
+#endif
diff --git a/vcl/inc/vcl/ppdparser.hxx b/vcl/inc/vcl/ppdparser.hxx
index ed9f91b97d99..ba5bc5004362 100644
--- a/vcl/inc/vcl/ppdparser.hxx
+++ b/vcl/inc/vcl/ppdparser.hxx
@@ -37,11 +37,14 @@
#include "tools/string.hxx"
#include "tools/stream.hxx"
+#include "com/sun/star/lang/Locale.hpp"
+
#define PRINTER_PPDDIR "driver"
namespace psp {
class PPDParser;
+class PPDTranslator;
enum PPDValueType { eInvocation, eQuoted, eSymbol, eString, eNo };
@@ -49,9 +52,7 @@ struct PPDValue
{
PPDValueType m_eType;
String m_aOption;
- String m_aOptionTranslation;
String m_aValue;
- String m_aValueTranslation;
};
// ----------------------------------------------------------------------
@@ -80,7 +81,6 @@ public:
private:
bool m_bUIOption;
- String m_aUITranslation;
UIType m_eUIType;
int m_nOrderDependency;
SetupType m_eSetupType;
@@ -102,7 +102,6 @@ public:
const String& getKey() const { return m_aKey; }
bool isUIKey() const { return m_bUIOption; }
- const String& getUITranslation() const { return m_aUITranslation; }
UIType getUIType() const { return m_eUIType; }
SetupType getSetupType() const { return m_eSetupType; }
int getOrderDependency() const { return m_nOrderDependency; }
@@ -185,6 +184,9 @@ private:
// fonts
const PPDKey* m_pFontList;
+ // translations
+ PPDTranslator* m_pTranslator;
+
PPDParser( const String& rFile );
~PPDParser();
@@ -193,7 +195,7 @@ private:
void parseConstraint( const ByteString& rLine );
void parse( std::list< ByteString >& rLines );
- String handleTranslation( const ByteString& rString );
+ String handleTranslation( const ByteString& i_rString, bool i_bIsGlobalized );
static void scanPPDDir( const String& rDir );
static void initPPDFiles();
@@ -277,6 +279,17 @@ public:
String& rEncoding,
String& rCharset ) const;
const String& getFont( int ) const;
+
+
+ rtl::OUString translateKey( const rtl::OUString& i_rKey,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const;
+ rtl::OUString translateOption( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const;
+ rtl::OUString translateValue( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rValue,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const;
};
// ----------------------------------------------------------------------
diff --git a/vcl/inc/vcl/printerinfomanager.hxx b/vcl/inc/vcl/printerinfomanager.hxx
index 810ad428c9db..2fb6ef1c2413 100644
--- a/vcl/inc/vcl/printerinfomanager.hxx
+++ b/vcl/inc/vcl/printerinfomanager.hxx
@@ -136,6 +136,7 @@ protected:
Type m_eType;
bool m_bUseIncludeFeature;
+ bool m_bUseJobPatch;
rtl::OUString m_aSystemDefaultPaper;
bool m_bDisableCUPS;
@@ -226,6 +227,7 @@ public:
virtual bool addOrRemovePossible() const;
bool getUseIncludeFeature() const { return m_bUseIncludeFeature; }
+ bool getUseJobPatch() const { return m_bUseJobPatch; }
// check whether a printer's feature string contains a subfeature
bool checkFeatureToken( const rtl::OUString& rPrinterName, const char* pToken ) const;
diff --git a/vcl/inc/vcl/tabctrl.hxx b/vcl/inc/vcl/tabctrl.hxx
index f6646426b2e7..e91dc47690ff 100644
--- a/vcl/inc/vcl/tabctrl.hxx
+++ b/vcl/inc/vcl/tabctrl.hxx
@@ -98,6 +98,10 @@ private:
DECL_DLLPRIVATE_LINK( ImplScrollBtnHdl, PushButton* pBtn );
DECL_DLLPRIVATE_LINK( ImplListBoxSelectHdl, ListBox* );
+public:
+ // just for dialog control
+ SAL_DLLPRIVATE bool ImplHandleNotifyEvent( NotifyEvent& rEvt );
+
protected:
using Window::ImplInit;
SAL_DLLPRIVATE void ImplInit( Window* pParent, WinBits nStyle );
diff --git a/vcl/inc/vcl/tabdlg.hxx b/vcl/inc/vcl/tabdlg.hxx
index 5ec2bcad5225..ad79ebec4549 100644
--- a/vcl/inc/vcl/tabdlg.hxx
+++ b/vcl/inc/vcl/tabdlg.hxx
@@ -36,6 +36,7 @@
#include <vcl/dialog.hxx>
class FixedLine;
+class TabControl;
// ----------------------
// - TabDialog -
@@ -61,6 +62,8 @@ public:
virtual void Resize();
virtual void StateChanged( StateChangedType nStateChange );
+ SAL_DLLPRIVATE TabControl* ImplGetFirstTabControl() const;
+
void AdjustLayout();
void SetViewWindow( Window* pWindow ) { mpViewWindow = pWindow; }
diff --git a/vcl/inc/vcl/vclevent.hxx b/vcl/inc/vcl/vclevent.hxx
index 74971f62c5a6..570c8ad0a342 100644
--- a/vcl/inc/vcl/vclevent.hxx
+++ b/vcl/inc/vcl/vclevent.hxx
@@ -36,12 +36,20 @@
#include "vcl/dllapi.h"
#include "vcl/impdel.hxx"
+#include <com/sun/star/uno/Reference.hxx>
+
#include <list>
#include <vector>
class Window;
class Menu;
+namespace com { namespace sun { namespace star {
+ namespace accessibility {
+ class XAccessible;
+ }
+}}}
+
#define VCLEVENT_OBJECT_DYING 1
// VclWindowEvent:
@@ -242,6 +250,17 @@ public:
USHORT GetItemPos() const { return mnPos; }
};
+class VCL_DLLPUBLIC VclAccessibleEvent: public VclSimpleEvent
+{
+public:
+ VclAccessibleEvent( ULONG n, const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& rxAccessible );
+ virtual ~VclAccessibleEvent();
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > GetAccessible() const;
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxAccessible;
+};
+
class VCL_DLLPUBLIC VclEventListeners : public std::list<Link>
{
public:
@@ -262,7 +281,10 @@ class VCL_DLLPUBLIC VclEventListeners2 : public vcl::DeletionNotifier
std::list< Link >::iterator m_aIt;
bool m_bWasInvalidated;
- ListenerIt() : m_bWasInvalidated( false ) {}
+ ListenerIt(const std::list<Link>::iterator& rIt)
+ : m_aIt(rIt)
+ , m_bWasInvalidated( false )
+ {}
};
std::vector< ListenerIt > m_aIterators;
diff --git a/vcl/inc/vcl/window.h b/vcl/inc/vcl/window.h
index 563849873e3b..0fec51e2e702 100644
--- a/vcl/inc/vcl/window.h
+++ b/vcl/inc/vcl/window.h
@@ -359,7 +359,8 @@ public:
mbCallHandlersDuringInputDisabled:1,
mbDisableAccessibleLabelForRelation:1,
mbDisableAccessibleLabeledByRelation:1,
- mbHelpTextDynamic:1;
+ mbHelpTextDynamic:1,
+ mbFakeFocusSet:1;
::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > mxDNDListenerContainer;
};
diff --git a/vcl/inc/vcl/window.hxx b/vcl/inc/vcl/window.hxx
index 56fdb22ddc57..c14ee7add4fb 100644
--- a/vcl/inc/vcl/window.hxx
+++ b/vcl/inc/vcl/window.hxx
@@ -582,7 +582,7 @@ protected:
void ImplCallEventListeners( ULONG nEvent, void* pData = NULL );
void CallEventListeners( ULONG nEvent, void* pData = NULL );
-
+ void FireVclEvent( VclSimpleEvent* pEvent );
// FIXME: this is a hack to workaround missing layout functionality
SAL_DLLPRIVATE void ImplAdjustNWFSizes();
@@ -899,6 +899,13 @@ public:
USHORT GetGetFocusFlags() const;
void GrabFocusToDocument();
+ /**
+ * Set this when you need to act as if the window has focus even if it
+ * doesn't. This is necessary for implementing tab stops inside floating
+ * windows, but floating windows don't get focus from the system.
+ */
+ void SetFakeFocus( bool bFocus );
+
BOOL IsCompoundControl() const;
BOOL HasCompoundControlFocus() const;
diff --git a/vcl/prj/build.lst b/vcl/prj/build.lst
index cf2824f72942..e6f636522acb 100644
--- a/vcl/prj/build.lst
+++ b/vcl/prj/build.lst
@@ -1,4 +1,4 @@
-vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools transex3 icc SO:print_header cpputools shell svl NULL
+vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools l10ntools icc SO:print_header cpputools shell svl NULL
vc vcl usr1 - all vc_mkout NULL
vc vcl\inc nmake - all vc_inc NULL
vc vcl\source\glyphs nmake - all vc_glyphs vc_inc NULL
diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst
index b106ff73729e..8345b155ce58 100644
--- a/vcl/prj/d.lst
+++ b/vcl/prj/d.lst
@@ -84,6 +84,7 @@ mkdir: %_DEST%\inc%_EXT%\vcl
..\inc\vcl\oldprintadaptor.hxx %_DEST%\inc%_EXT%\vcl\oldprintadaptor.hxx
..\inc\vcl\outdev.hxx %_DEST%\inc%_EXT%\vcl\outdev.hxx
..\inc\vcl\pointr.hxx %_DEST%\inc%_EXT%\vcl\pointr.hxx
+..\inc\vcl\popupmenuwindow.hxx %_DEST%\inc%_EXT%\vcl\popupmenuwindow.hxx
..\inc\vcl\print.hxx %_DEST%\inc%_EXT%\vcl\print.hxx
..\inc\vcl\prntypes.hxx %_DEST%\inc%_EXT%\vcl\prntypes.hxx
..\inc\vcl\ptrstyle.hxx %_DEST%\inc%_EXT%\vcl\ptrstyle.hxx
diff --git a/vcl/source/app/vclevent.cxx b/vcl/source/app/vclevent.cxx
index 704d68c5bc7f..ffab843ff7bd 100644
--- a/vcl/source/app/vclevent.cxx
+++ b/vcl/source/app/vclevent.cxx
@@ -34,10 +34,30 @@
#include "vcl/vclevent.hxx"
#include "vcl/svdata.hxx"
+#include <com/sun/star/accessibility/XAccessible.hpp>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::accessibility::XAccessible;
+
TYPEINIT0(VclSimpleEvent);
TYPEINIT1(VclWindowEvent, VclSimpleEvent);
TYPEINIT1(VclMenuEvent, VclSimpleEvent);
+VclAccessibleEvent::VclAccessibleEvent( ULONG n, const Reference<XAccessible>& rxAccessible ) :
+ VclSimpleEvent(n),
+ mxAccessible(rxAccessible)
+{
+}
+
+VclAccessibleEvent::~VclAccessibleEvent()
+{
+}
+
+Reference<XAccessible> VclAccessibleEvent::GetAccessible() const
+{
+ return mxAccessible;
+}
+
void VclEventListeners::Call( VclSimpleEvent* pEvent ) const
{
// Copy the list, because this can be destroyed when calling a Link...
@@ -118,9 +138,8 @@ void VclEventListeners2::callListeners( VclSimpleEvent* i_pEvent )
{
vcl::DeletionListener aDel( this );
- m_aIterators.push_back( ListenerIt() );
+ m_aIterators.push_back(ListenerIt(m_aListeners.begin()));
size_t nIndex = m_aIterators.size() - 1;
- m_aIterators[ nIndex ].m_aIt = m_aListeners.begin();
while( ! aDel.isDeleted() && m_aIterators[ nIndex ].m_aIt != m_aListeners.end() )
{
m_aIterators[ nIndex ].m_aIt->Call( i_pEvent );
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index 21707d0182f5..1eea72131b86 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -951,7 +951,7 @@ void ComboBox::ImplUpdateFloatSelection()
if( nSelect != LISTBOX_ENTRY_NOTFOUND )
{
if ( !mpImplLB->IsVisible( nSelect ) )
- mpImplLB->SetTopEntry( nSelect );
+ mpImplLB->ShowProminentEntry( nSelect );
mpImplLB->SelectEntry( nSelect, bSelect );
}
else
@@ -959,7 +959,6 @@ void ComboBox::ImplUpdateFloatSelection()
nSelect = mpImplLB->GetEntryList()->GetSelectEntryPos( 0 );
if( nSelect != LISTBOX_ENTRY_NOTFOUND )
mpImplLB->SelectEntry( nSelect, FALSE );
- // mpImplLB->SetTopEntry( 0 ); #92555# Ugly....
mpImplLB->ResetCurrentPos();
}
}
@@ -1440,6 +1439,13 @@ void ComboBox::SetTopEntry( USHORT nPos )
// -----------------------------------------------------------------------
+void ComboBox::ShowProminentEntry( USHORT nPos )
+{
+ mpImplLB->ShowProminentEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
USHORT ComboBox::GetTopEntry() const
{
USHORT nPos = GetEntryCount() ? mpImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND;
@@ -1450,6 +1456,20 @@ USHORT ComboBox::GetTopEntry() const
// -----------------------------------------------------------------------
+void ComboBox::SetProminentEntryType( ProminentEntry eType )
+{
+ mpImplLB->SetProminentEntryType( eType );
+}
+
+// -----------------------------------------------------------------------
+
+ProminentEntry ComboBox::GetProminentEntryType() const
+{
+ return mpImplLB->GetProminentEntryType();
+}
+
+// -----------------------------------------------------------------------
+
Rectangle ComboBox::GetDropDownPosSizePixel() const
{
return mpFloatWin ? mpFloatWin->GetWindowExtentsRelative( const_cast<ComboBox*>(this) ) : Rectangle();
diff --git a/vcl/source/control/ilstbox.cxx b/vcl/source/control/ilstbox.cxx
index fd5cd7ae4dac..ab353a4d4798 100644
--- a/vcl/source/control/ilstbox.cxx
+++ b/vcl/source/control/ilstbox.cxx
@@ -565,6 +565,7 @@ ImplListBoxWindow::ImplListBoxWindow( Window* pParent, WinBits nWinStyle ) :
mnCurrentPos = LISTBOX_ENTRY_NOTFOUND;
mnTrackingSaveSelection = LISTBOX_ENTRY_NOTFOUND;
mnSeparatorPos = LISTBOX_ENTRY_NOTFOUND;
+ meProminentType = PROMINENT_TOP;
SetLineColor();
SetTextFillColor();
@@ -1067,11 +1068,11 @@ void ImplListBoxWindow::SelectEntry( USHORT nPos, BOOL bSelect )
if ( !nVisibleEntries || !IsReallyVisible() || ( nPos < GetTopEntry() ) )
{
Resize();
- SetTopEntry( nPos );
+ ShowProminentEntry( nPos );
}
else
{
- SetTopEntry( nPos-nVisibleEntries+1 );
+ ShowProminentEntry( nPos );
}
}
}
@@ -1702,11 +1703,7 @@ BOOL ImplListBoxWindow::ProcessKeyInput( const KeyEvent& rKEvt )
if ( nSelect != LISTBOX_ENTRY_NOTFOUND )
{
- USHORT nCurVis = GetLastVisibleEntry() - mnTop + 1;
- if( nSelect < mnTop )
- SetTopEntry( nSelect );
- else if( nSelect >= (mnTop + nCurVis) )
- SetTopEntry( nSelect - nCurVis + 1 );
+ ShowProminentEntry( nSelect );
if ( mpEntryList->IsEntryPosSelected( nSelect ) )
nSelect = LISTBOX_ENTRY_NOTFOUND;
@@ -2053,6 +2050,20 @@ void ImplListBoxWindow::SetTopEntry( USHORT nTop )
// -----------------------------------------------------------------------
+void ImplListBoxWindow::ShowProminentEntry( USHORT nEntryPos )
+{
+ if( meProminentType == PROMINENT_MIDDLE )
+ {
+ USHORT nPos = nEntryPos;
+ long nWHeight = PixelToLogic( GetSizePixel() ).Height();
+ while( nEntryPos > 0 && mpEntryList->GetAddedHeight( nPos+1, nEntryPos ) < nWHeight/2 )
+ nEntryPos--;
+ }
+ SetTopEntry( nEntryPos );
+}
+
+// -----------------------------------------------------------------------
+
void ImplListBoxWindow::SetLeftIndent( long n )
{
ScrollHorz( n - mnLeft );
@@ -3206,7 +3217,7 @@ void ImplListBoxFloatingWindow::StartFloat( BOOL bStartTracking )
StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );
if( nPos != LISTBOX_ENTRY_NOTFOUND )
- mpImplLB->SetTopEntry( nPos );
+ mpImplLB->ShowProminentEntry( nPos );
if( bStartTracking )
mpImplLB->GetMainWindow()->EnableMouseMoveSelect( TRUE );
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index 81a8dc0e8242..ac51d7593c93 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -1210,6 +1210,13 @@ void ListBox::SetTopEntry( USHORT nPos )
// -----------------------------------------------------------------------
+void ListBox::ShowProminentEntry( USHORT nPos )
+{
+ mpImplLB->ShowProminentEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() );
+}
+
+// -----------------------------------------------------------------------
+
USHORT ListBox::GetTopEntry() const
{
USHORT nPos = GetEntryCount() ? mpImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND;
@@ -1220,6 +1227,20 @@ USHORT ListBox::GetTopEntry() const
// -----------------------------------------------------------------------
+void ListBox::SetProminentEntryType( ProminentEntry eType )
+{
+ mpImplLB->SetProminentEntryType( eType );
+}
+
+// -----------------------------------------------------------------------
+
+ProminentEntry ListBox::GetProminentEntryType() const
+{
+ return mpImplLB->GetProminentEntryType();
+}
+
+// -----------------------------------------------------------------------
+
BOOL ListBox::IsTravelSelect() const
{
return mpImplLB->IsTravelSelect();
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 56cc2c3fb012..43c459b6c52e 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -1658,7 +1658,7 @@ long TabControl::PreNotify( NotifyEvent& rNEvt )
// -----------------------------------------------------------------------
-long TabControl::Notify( NotifyEvent& rNEvt )
+bool TabControl::ImplHandleNotifyEvent( NotifyEvent& rNEvt )
{
if ( (rNEvt.GetType() == EVENT_KEYINPUT) && (GetPageCount() > 1) )
{
@@ -1686,8 +1686,16 @@ long TabControl::Notify( NotifyEvent& rNEvt )
}
}
}
+ return false;
+}
+
+
+// -----------------------------------------------------------------------
+
+long TabControl::Notify( NotifyEvent& rNEvt )
+{
- return Control::Notify( rNEvt );
+ return ImplHandleNotifyEvent( rNEvt ) ? TRUE : Control::Notify( rNEvt );
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/fontsubset/gsub.cxx b/vcl/source/fontsubset/gsub.cxx
index 600c03194210..a1c3344f3e5a 100644
--- a/vcl/source/fontsubset/gsub.cxx
+++ b/vcl/source/fontsubset/gsub.cxx
@@ -42,6 +42,7 @@ namespace vcl
{
typedef sal_uInt32 ULONG;
+typedef sal_uInt32 UINT32;
typedef sal_uInt16 USHORT;
typedef sal_uInt8 FT_Byte;
@@ -280,13 +281,11 @@ int ReadGSUB( struct _TrueTypeFont* pTTFile,
return false;
for( int i = nCntRange; --i >= 0; )
{
- const USHORT nGlyph0 = NEXT_UShort( pCoverage );
- const USHORT nGlyph1 = NEXT_UShort( pCoverage );
- const USHORT nStartCoverageIndex = NEXT_UShort( pCoverage );
- OSL_ENSURE( aSubstVector.size() == nStartCoverageIndex, "coverage index mismatch");
- (void)nStartCoverageIndex;
- for( USHORT j = nGlyph0; j <= nGlyph1; ++j )
- aSubstVector.push_back( GlyphSubst( j, 0 ) );
+ const UINT32 nGlyph0 = NEXT_UShort( pCoverage );
+ const UINT32 nGlyph1 = NEXT_UShort( pCoverage );
+ const USHORT nCovIdx = NEXT_UShort( pCoverage );
+ for( UINT32 j = nGlyph0; j <= nGlyph1; ++j )
+ aSubstVector.push_back( GlyphSubst( static_cast<USHORT>(j + nCovIdx), 0 ) );
}
}
break;
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 0accc42af968..964d6a93ac3c 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1094,6 +1094,14 @@ static void GetNames(TrueTypeFont *t)
const sal_uInt8* table = getTable( t, O_name );
int nTableSize = getTableSize(t, O_name);
+ if (nTableSize < 4)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf(stderr, "O_name table too small\n");
+#endif
+ return;
+ }
+
sal_uInt16 n = GetUInt16(table, 2, 1);
int i, r;
sal_Bool bPSNameOK = sal_True;
@@ -1681,7 +1689,6 @@ int OpenTTFontFile( const char* fname, sal_uInt32 facenum, TrueTypeFont** ttf )
goto cleanup;
}
-
if (((*ttf)->ptr = (sal_uInt8 *) mmap(0, (*ttf)->fsize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
ret = SF_MEMORY;
goto cleanup;
@@ -2702,7 +2709,7 @@ void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info)
}
table = getTable(ttf, O_post);
- if (table) {
+ if (table && getTableSize(ttf, O_post) >= 12+sizeof(sal_uInt32)) {
info->pitch = GetUInt32(table, 12, 1);
info->italicAngle = GetInt32(table, 4, 1);
}
@@ -2808,6 +2815,15 @@ int GetTTNameRecords(TrueTypeFont *ttf, NameRecord **nr)
{
const sal_uInt8* table = getTable(ttf, O_name);
int nTableSize = getTableSize(ttf, O_name );
+
+ if (nTableSize < 6)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf(stderr, "O_name table too small\n");
+#endif
+ return 0;
+ }
+
sal_uInt16 n = GetUInt16(table, 2, 1);
int nStrBase = GetUInt16(table, 4, 1);
int i;
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index 51aad0790a26..28fa4f8f5461 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -5601,6 +5601,8 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const String& rStr,
if ( !IsDeviceOutputNecessary() )
return;
+ if( !mpGraphics && !ImplGetGraphics() )
+ return;
if( mbInitClipRegion )
ImplInitClipRegion();
if( mbOutputClipped )
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index c0205f1f325d..d42e736960d2 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -2814,37 +2814,6 @@ sal_Int32 PDFWriterImpl::emitBuiltinFont( const ImplFontData* pFont, sal_Int32 n
return nFontObject;
}
-typedef int ThreeInts[3];
-static bool getPfbSegmentLengths( const unsigned char* pFontBytes, int nByteLen,
- ThreeInts& rSegmentLengths )
-{
- if( !pFontBytes || (nByteLen < 0) )
- return false;
- const unsigned char* pPtr = pFontBytes;
- const unsigned char* pEnd = pFontBytes + nByteLen;
-
- for( int i = 0; i < 3; ++i) {
- // read segment1 header
- if( pPtr+6 >= pEnd )
- return false;
- if( (pPtr[0] != 0x80) || (pPtr[1] >= 0x03) )
- return false;
- const int nLen = (pPtr[5]<<24) + (pPtr[4]<<16) + (pPtr[3]<<8) + pPtr[2];
- if( nLen <= 0)
- return false;
- rSegmentLengths[i] = nLen;
- pPtr += nLen + 6;
- }
-
- // read segment-end header
- if( pPtr+2 >= pEnd )
- return false;
- if( (pPtr[0] != 0x80) || (pPtr[1] != 0x03) )
- return false;
-
- return true;
-}
-
std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitSystemFont( const ImplFontData* pFont, EmbedFont& rEmbed )
{
std::map< sal_Int32, sal_Int32 > aRet;
@@ -2960,6 +2929,41 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitSystemFont( const ImplFontDa
return aRet;
}
+typedef int ThreeInts[3];
+static bool getPfbSegmentLengths( const unsigned char* pFontBytes, int nByteLen,
+ ThreeInts& rSegmentLengths )
+{
+ if( !pFontBytes || (nByteLen < 0) )
+ return false;
+ const unsigned char* pPtr = pFontBytes;
+ const unsigned char* pEnd = pFontBytes + nByteLen;
+
+ for( int i = 0; i < 3; ++i) {
+ // read segment1 header
+ if( pPtr+6 >= pEnd )
+ return false;
+ if( (pPtr[0] != 0x80) || (pPtr[1] >= 0x03) )
+ return false;
+ const int nLen = (pPtr[5]<<24) + (pPtr[4]<<16) + (pPtr[3]<<8) + pPtr[2];
+ if( nLen <= 0)
+ return false;
+ rSegmentLengths[i] = nLen;
+ pPtr += nLen + 6;
+ }
+
+ // read segment-end header
+ if( pPtr+2 >= pEnd )
+ return false;
+ if( (pPtr[0] != 0x80) || (pPtr[1] != 0x03) )
+ return false;
+
+ return true;
+}
+
+struct FontException : public std::exception
+{
+};
+
// TODO: always subset instead of embedding the full font => this method becomes obsolete then
std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitEmbeddedFont( const ImplFontData* pFont, EmbedFont& rEmbed )
{
@@ -2979,10 +2983,16 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitEmbeddedFont( const ImplFont
sal_Int32 nToUnicodeStream = 0;
sal_uInt8 nEncoding[256];
sal_Ucs nEncodedCodes[256];
+ std::vector<sal_Ucs> aUnicodes;
+ aUnicodes.reserve( 256 );
+ sal_Int32 pUnicodesPerGlyph[256];
+ sal_Int32 pEncToUnicodeIndex[256];
if( pEncoding )
{
- memset( nEncodedCodes, 0, sizeof(nEncodedCodes) );
- memset( nEncoding, 0, sizeof(nEncoding) );
+ rtl_zeroMemory( nEncoding, sizeof(nEncoding) );
+ rtl_zeroMemory( nEncodedCodes, sizeof(nEncodedCodes) );
+ rtl_zeroMemory( pUnicodesPerGlyph, sizeof(pUnicodesPerGlyph) );
+ rtl_zeroMemory( pEncToUnicodeIndex, sizeof(pEncToUnicodeIndex) );
for( Ucs2SIntMap::const_iterator it = pEncoding->begin(); it != pEncoding->end(); ++it )
{
if( it->second != -1 )
@@ -2990,6 +3000,9 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitEmbeddedFont( const ImplFont
sal_Int32 nCode = (sal_Int32)(it->second & 0x000000ff);
nEncoding[ nCode ] = static_cast<sal_uInt8>( nCode );
nEncodedCodes[ nCode ] = it->first;
+ pEncToUnicodeIndex[ nCode ] = static_cast<sal_Int32>(aUnicodes.size());
+ aUnicodes.push_back( it->first );
+ pUnicodesPerGlyph[ nCode ] = 1;
}
}
}
@@ -2999,553 +3012,525 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitEmbeddedFont( const ImplFont
const unsigned char* pFontData = NULL;
long nFontLen = 0;
sal_Int32 nLength1, nLength2;
- if( (pFontData = (const unsigned char*)m_pReferenceDevice->mpGraphics->GetEmbedFontData( pFont, nEncodedCodes, pWidths, aInfo, &nFontLen )) != NULL )
- {
- if( (aInfo.m_nFontType & FontSubsetInfo::ANY_TYPE1) == 0 )
- goto streamend;
- // see whether it is pfb or pfa; if it is a pfb, fill ranges
- // of 6 bytes that are not part of the font program
- std::list< int > aSections;
- std::list< int >::const_iterator it;
- int nIndex = 0;
- while( pFontData[nIndex] == 0x80 && nIndex < nFontLen-1 )
- {
- aSections.push_back( nIndex );
- if( pFontData[nIndex+1] == 0x03 )
- break;
- sal_Int32 nBytes =
+ try
+ {
+ if( (pFontData = (const unsigned char*)m_pReferenceDevice->mpGraphics->GetEmbedFontData( pFont, nEncodedCodes, pWidths, aInfo, &nFontLen )) != NULL )
+ {
+ if( (aInfo.m_nFontType & FontSubsetInfo::ANY_TYPE1) == 0 )
+ throw FontException();
+ // see whether it is pfb or pfa; if it is a pfb, fill ranges
+ // of 6 bytes that are not part of the font program
+ std::list< int > aSections;
+ std::list< int >::const_iterator it;
+ int nIndex = 0;
+ while( pFontData[nIndex] == 0x80 && nIndex < nFontLen-1 )
+ {
+ aSections.push_back( nIndex );
+ if( pFontData[nIndex+1] == 0x03 )
+ break;
+ sal_Int32 nBytes =
((sal_Int32)pFontData[nIndex+2]) |
((sal_Int32)pFontData[nIndex+3]) << 8 |
((sal_Int32)pFontData[nIndex+4]) << 16 |
((sal_Int32)pFontData[nIndex+5]) << 24;
- nIndex += nBytes+6;
- }
-
- // search for eexec
- // TODO: use getPfbSegmentLengths() if possible to skip the search thingies below
- nIndex = 0;
- int nEndAsciiIndex;
- int nBeginBinaryIndex;
- int nEndBinaryIndex;
- do
- {
- while( nIndex < nFontLen-4 &&
- ( pFontData[nIndex] != 'e' ||
- pFontData[nIndex+1] != 'e' ||
- pFontData[nIndex+2] != 'x' ||
- pFontData[nIndex+3] != 'e' ||
- pFontData[nIndex+4] != 'c'
- )
- )
- nIndex++;
- // check whether we are in a excluded section
- for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it )
- ;
- } while( it != aSections.end() && nIndex < nFontLen-4 );
- // this should end the ascii part
- if( nIndex > nFontLen-5 )
- goto streamend;
-
- nEndAsciiIndex = nIndex+4;
- // now count backwards until we can account for 512 '0'
- // which is the endmarker of the (hopefully) binary data
- // do not count the pfb header sections
- int nFound = 0;
- nIndex = nFontLen-1;
- while( nIndex > 0 && nFound < 512 )
- {
- for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it )
- ;
- if( it == aSections.end() )
- {
- // inside the 512 '0' block there may only be whitespace
- // according to T1 spec; probably it would be to simple
- // if all fonts complied
- if( pFontData[nIndex] == '0' )
- nFound++;
- else if( nFound > 0 &&
- pFontData[nIndex] != '\r' &&
- pFontData[nIndex] != '\t' &&
- pFontData[nIndex] != '\n' &&
- pFontData[nIndex] != ' ' )
- break;
+ nIndex += nBytes+6;
}
- nIndex--;
- }
-
- if( nIndex < 1 || nIndex <= nEndAsciiIndex )
- goto streamend;
- // there may be whitespace to ignore before the 512 '0'
- while( pFontData[nIndex] == '\r' || pFontData[nIndex] == '\n' )
- {
- nIndex--;
- for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it )
- ;
- if( it != aSections.end() )
- {
- nIndex = (*it)-1;
- break; // this is surely a binary boundary, in ascii case it wouldn't matter
- }
- }
- nEndBinaryIndex = nIndex;
- // and count forward again to the point where we have nFound '0'
- // to get the corect value for nLength3
- sal_Int32 nLength3 = 0;
- sal_Int32 nL3Index = nIndex;
- while( nFound && nL3Index < nFontLen )
- {
- for( it = aSections.begin(); it != aSections.end() && (nL3Index < *it || nL3Index > ((*it) + 5) ); ++it )
- ;
- if( it == aSections.end() )
+ // search for eexec
+ // TODO: use getPfbSegmentLengths() if possible to skip the search thingies below
+ nIndex = 0;
+ int nEndAsciiIndex;
+ int nBeginBinaryIndex;
+ int nEndBinaryIndex;
+ do
{
- // inside the 512 '0' block there may only be whitespace
- // according to T1 spec; probably it would be to simple
- // if all fonts complied
- if( pFontData[nL3Index] == '0' )
- nFound--;
- nLength3++;
- }
- nL3Index++;
- }
-
- // search for beginning of binary section
- nBeginBinaryIndex = nEndAsciiIndex;
- do
- {
- nBeginBinaryIndex++;
- for( it = aSections.begin(); it != aSections.end() && (nBeginBinaryIndex < *it || nBeginBinaryIndex > ((*it) + 5) ); ++it )
- ;
- } while( nBeginBinaryIndex < nEndBinaryIndex &&
- ( pFontData[nBeginBinaryIndex] == '\r' ||
- pFontData[nBeginBinaryIndex] == '\n' ||
- it != aSections.end() ) );
-
- // it seems to be vital to copy the exact whitespace between binary data
- // and eexec, else a invalid font results. so make nEndAsciiIndex
- // always immediate in front of nBeginBinaryIndex
- nEndAsciiIndex = nBeginBinaryIndex-1;
- for( it = aSections.begin(); it != aSections.end() && (nEndAsciiIndex < *it || nEndAsciiIndex > ((*it)+5)); ++it )
- ;
- if( it != aSections.end() )
- nEndAsciiIndex = (*it)-1;
-
- nLength1 = nEndAsciiIndex+1; // including the last character
- for( it = aSections.begin(); it != aSections.end() && *it < nEndAsciiIndex; ++it )
- nLength1 -= 6; // decrease by pfb section size
-
- // if the first four bytes are all ascii hex characters, then binary data
- // has to be converted to real binary data
- for( nIndex = 0; nIndex < 4 &&
- ( ( pFontData[ nBeginBinaryIndex+nIndex ] >= '0' && pFontData[ nBeginBinaryIndex+nIndex ] <= '9' ) ||
- ( pFontData[ nBeginBinaryIndex+nIndex ] >= 'a' && pFontData[ nBeginBinaryIndex+nIndex ] <= 'f' ) ||
- ( pFontData[ nBeginBinaryIndex+nIndex ] >= 'A' && pFontData[ nBeginBinaryIndex+nIndex ] <= 'F' )
- ); ++nIndex )
- ;
- bool bConvertHexData = true;
- if( nIndex < 4 )
- {
- bConvertHexData = false;
- nLength2 = nEndBinaryIndex - nBeginBinaryIndex + 1; // include the last byte
- for( it = aSections.begin(); it != aSections.end(); ++it )
- if( *it > nBeginBinaryIndex && *it < nEndBinaryIndex )
- nLength2 -= 6;
- }
- else
- {
- // count the hex ascii characters to get nLength2
- nLength2 = 0;
- int nNextSectionIndex = 0;
- for( it = aSections.begin(); it != aSections.end() && *it < nBeginBinaryIndex; ++it )
- ;
- if( it != aSections.end() )
- nNextSectionIndex = *it;
- for( nIndex = nBeginBinaryIndex; nIndex <= nEndBinaryIndex; nIndex++ )
+ while( nIndex < nFontLen-4 &&
+ ( pFontData[nIndex] != 'e' ||
+ pFontData[nIndex+1] != 'e' ||
+ pFontData[nIndex+2] != 'x' ||
+ pFontData[nIndex+3] != 'e' ||
+ pFontData[nIndex+4] != 'c'
+ )
+ )
+ nIndex++;
+ // check whether we are in a excluded section
+ for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it )
+ ;
+ } while( it != aSections.end() && nIndex < nFontLen-4 );
+ // this should end the ascii part
+ if( nIndex > nFontLen-5 )
+ throw FontException();
+
+ nEndAsciiIndex = nIndex+4;
+ // now count backwards until we can account for 512 '0'
+ // which is the endmarker of the (hopefully) binary data
+ // do not count the pfb header sections
+ int nFound = 0;
+ nIndex = nFontLen-1;
+ while( nIndex > 0 && nFound < 512 )
{
- if( nIndex == nNextSectionIndex )
+ for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it )
+ ;
+ if( it == aSections.end() )
{
- nIndex += 6;
- ++it;
- nNextSectionIndex = (it == aSections.end() ? 0 : *it );
+ // inside the 512 '0' block there may only be whitespace
+ // according to T1 spec; probably it would be to simple
+ // if all fonts complied
+ if( pFontData[nIndex] == '0' )
+ nFound++;
+ else if( nFound > 0 &&
+ pFontData[nIndex] != '\r' &&
+ pFontData[nIndex] != '\t' &&
+ pFontData[nIndex] != '\n' &&
+ pFontData[nIndex] != ' ' )
+ break;
}
- if( ( pFontData[ nIndex ] >= '0' && pFontData[ nIndex ] <= '9' ) ||
- ( pFontData[ nIndex ] >= 'a' && pFontData[ nIndex ] <= 'f' ) ||
- ( pFontData[ nIndex ] >= 'A' && pFontData[ nIndex ] <= 'F' ) )
- nLength2++;
+ nIndex--;
}
- DBG_ASSERT( !(nLength2 & 1), "uneven number of hex chars in binary pfa section" );
- nLength2 /= 2;
- }
-
- // now we can actually write the font stream !
-#if OSL_DEBUG_LEVEL > 1
- {
- OStringBuffer aLine( " PDFWriterImpl::emitEmbeddedFont" );
- emitComment( aLine.getStr() );
- }
-#endif
- OStringBuffer aLine( 512 );
- nStreamObject = createObject();
- if( !updateObject(nStreamObject))
- goto streamend;
- sal_Int32 nStreamLengthObject = createObject();
- aLine.append( nStreamObject );
- aLine.append( " 0 obj\n"
- "<</Length " );
- aLine.append( nStreamLengthObject );
- aLine.append( " 0 R"
-#ifndef DEBUG_DISABLE_PDFCOMPRESSION
- "/Filter/FlateDecode"
-#endif
- "/Length1 " );
- aLine.append( nLength1 );
- aLine.append( " /Length2 " );
- aLine.append( nLength2 );
- aLine.append( " /Length3 ");
- aLine.append( nLength3 );
- aLine.append( ">>\n"
- "stream\n" );
- if( !writeBuffer( aLine.getStr(), aLine.getLength() ) )
- goto streamend;
- sal_uInt64 nBeginStreamPos = 0;
- osl_getFilePos( m_aFile, &nBeginStreamPos );
+ if( nIndex < 1 || nIndex <= nEndAsciiIndex )
+ throw FontException();
- beginCompression();
- checkAndEnableStreamEncryption( nStreamObject );
-
- // write ascii section
- if( aSections.begin() == aSections.end() )
- {
- if( ! writeBuffer( pFontData, nEndAsciiIndex+1 ) )
- {
- endCompression();
- disableStreamEncryption();
- goto streamend;
- }
- }
- else
- {
- // first section always starts at 0
- it = aSections.begin();
- nIndex = (*it)+6;
- ++it;
- while( *it < nEndAsciiIndex )
+ // nLength3 is the rest of the file - excluding any section headers
+ // nIndex now points to the first of the 512 '0' characters marking the
+ // fixed content portion
+ sal_Int32 nLength3 = nFontLen - nIndex;
+ for( it = aSections.begin(); it != aSections.end(); ++it )
{
- if( ! writeBuffer( pFontData+nIndex, (*it)-nIndex ) )
+ if( *it >= nIndex )
{
- endCompression();
- disableStreamEncryption();
- goto streamend;
+ // special case: nIndex inside a section marker
+ if( nIndex >= (*it) && (*it)+5 > nIndex )
+ nLength3 -= (*it)+5 - nIndex;
+ else
+ {
+ if( *it < nFontLen - 6 )
+ nLength3 -= 6;
+ else // the last section 0x8003 is only 2 bytes after all
+ nLength3 -= (nFontLen - *it);
+ }
}
- nIndex = (*it)+6;
- ++it;
}
- // write partial last section
- if( ! writeBuffer( pFontData+nIndex, nEndAsciiIndex-nIndex+1 ) )
- {
- endCompression();
- disableStreamEncryption();
- goto streamend;
- }
- }
- // write binary section
- if( ! bConvertHexData )
- {
- if( aSections.begin() == aSections.end() )
+ // there may be whitespace to ignore before the 512 '0'
+ while( pFontData[nIndex] == '\r' || pFontData[nIndex] == '\n' )
{
- if( ! writeBuffer( pFontData+nBeginBinaryIndex, nFontLen-nBeginBinaryIndex ) )
+ nIndex--;
+ for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it )
+ ;
+ if( it != aSections.end() )
{
- endCompression();
- disableStreamEncryption();
- goto streamend;
+ nIndex = (*it)-1;
+ break; // this is surely a binary boundary, in ascii case it wouldn't matter
}
}
- else
+ nEndBinaryIndex = nIndex;
+
+ // search for beginning of binary section
+ nBeginBinaryIndex = nEndAsciiIndex;
+ do
{
- for( it = aSections.begin(); *it < nBeginBinaryIndex; ++it )
+ nBeginBinaryIndex++;
+ for( it = aSections.begin(); it != aSections.end() && (nBeginBinaryIndex < *it || nBeginBinaryIndex > ((*it) + 5) ); ++it )
;
- // write first partial section
- if( ! writeBuffer( pFontData+nBeginBinaryIndex, (*it) - nBeginBinaryIndex ) )
- {
- endCompression();
- disableStreamEncryption();
- goto streamend;
- }
- // write following sections
- while( it != aSections.end() )
- {
- nIndex = (*it)+6;
- ++it;
- if( nIndex < nFontLen ) // last section marker is usually the EOF which has only 2 bytes
+ } while( nBeginBinaryIndex < nEndBinaryIndex &&
+ ( pFontData[nBeginBinaryIndex] == '\r' ||
+ pFontData[nBeginBinaryIndex] == '\n' ||
+ it != aSections.end() ) );
+
+ // it seems to be vital to copy the exact whitespace between binary data
+ // and eexec, else a invalid font results. so make nEndAsciiIndex
+ // always immediate in front of nBeginBinaryIndex
+ nEndAsciiIndex = nBeginBinaryIndex-1;
+ for( it = aSections.begin(); it != aSections.end() && (nEndAsciiIndex < *it || nEndAsciiIndex > ((*it)+5)); ++it )
+ ;
+ if( it != aSections.end() )
+ nEndAsciiIndex = (*it)-1;
+
+ nLength1 = nEndAsciiIndex+1; // including the last character
+ for( it = aSections.begin(); it != aSections.end() && *it < nEndAsciiIndex; ++it )
+ nLength1 -= 6; // decrease by pfb section size
+
+ // if the first four bytes are all ascii hex characters, then binary data
+ // has to be converted to real binary data
+ for( nIndex = 0; nIndex < 4 &&
+ ( ( pFontData[ nBeginBinaryIndex+nIndex ] >= '0' && pFontData[ nBeginBinaryIndex+nIndex ] <= '9' ) ||
+ ( pFontData[ nBeginBinaryIndex+nIndex ] >= 'a' && pFontData[ nBeginBinaryIndex+nIndex ] <= 'f' ) ||
+ ( pFontData[ nBeginBinaryIndex+nIndex ] >= 'A' && pFontData[ nBeginBinaryIndex+nIndex ] <= 'F' )
+ ); ++nIndex )
+ ;
+ bool bConvertHexData = true;
+ if( nIndex < 4 )
+ {
+ bConvertHexData = false;
+ nLength2 = nEndBinaryIndex - nBeginBinaryIndex + 1; // include the last byte
+ for( it = aSections.begin(); it != aSections.end(); ++it )
+ if( *it > nBeginBinaryIndex && *it < nEndBinaryIndex )
+ nLength2 -= 6;
+ }
+ else
{
- sal_Int32 nSectionLen = (it == aSections.end()) ? nFontLen - nIndex : (*it) - nIndex;
- if( ! writeBuffer( pFontData+nIndex, nSectionLen ) )
+ // count the hex ascii characters to get nLength2
+ nLength2 = 0;
+ int nNextSectionIndex = 0;
+ for( it = aSections.begin(); it != aSections.end() && *it < nBeginBinaryIndex; ++it )
+ ;
+ if( it != aSections.end() )
+ nNextSectionIndex = *it;
+ for( nIndex = nBeginBinaryIndex; nIndex <= nEndBinaryIndex; nIndex++ )
{
- endCompression();
- disableStreamEncryption();
- goto streamend;
+ if( nIndex == nNextSectionIndex )
+ {
+ nIndex += 6;
+ ++it;
+ nNextSectionIndex = (it == aSections.end() ? 0 : *it );
+ }
+ if( ( pFontData[ nIndex ] >= '0' && pFontData[ nIndex ] <= '9' ) ||
+ ( pFontData[ nIndex ] >= 'a' && pFontData[ nIndex ] <= 'f' ) ||
+ ( pFontData[ nIndex ] >= 'A' && pFontData[ nIndex ] <= 'F' ) )
+ nLength2++;
}
+ DBG_ASSERT( !(nLength2 & 1), "uneven number of hex chars in binary pfa section" );
+ nLength2 /= 2;
}
- }
- }
- }
- else
- {
- unsigned char* pWriteBuffer = (unsigned char*)rtl_allocateMemory( nLength2 );
- memset( pWriteBuffer, 0, nLength2 );
- int nWriteIndex = 0;
-
- int nNextSectionIndex = 0;
- for( it = aSections.begin(); it != aSections.end() && *it < nBeginBinaryIndex; ++it )
- ;
- if( it != aSections.end() )
- nNextSectionIndex = *it;
- for( nIndex = nBeginBinaryIndex; nIndex <= nEndBinaryIndex; nIndex++ )
- {
- if( nIndex == nNextSectionIndex )
- {
- nIndex += 6;
- ++it;
- nNextSectionIndex = (it == aSections.end() ? nFontLen : *it );
- }
- unsigned char cNibble = 0x80;
- if( pFontData[ nIndex ] >= '0' && pFontData[ nIndex ] <= '9' )
- cNibble = pFontData[nIndex] - '0';
- else if( pFontData[ nIndex ] >= 'a' && pFontData[ nIndex ] <= 'f' )
- cNibble = pFontData[nIndex] - 'a' + 10;
- else if( pFontData[ nIndex ] >= 'A' && pFontData[ nIndex ] <= 'F' )
- cNibble = pFontData[nIndex] - 'A' + 10;
- if( cNibble != 0x80 )
- {
- if( !(nWriteIndex & 1 ) )
- cNibble <<= 4;
- pWriteBuffer[ nWriteIndex/2 ] |= cNibble;
- nWriteIndex++;
- }
- }
- if( ! writeBuffer( pWriteBuffer, nLength2 ) )
- {
- endCompression();
- disableStreamEncryption();
- goto streamend;
- }
- rtl_freeMemory( pWriteBuffer );
- if( aSections.empty() )
- {
- if( ! writeBuffer( pFontData+nIndex, nFontLen-nIndex ) )
- {
- endCompression();
- disableStreamEncryption();
- goto streamend;
- }
- }
- else
- {
- // write rest of this section
- if( nIndex < nNextSectionIndex )
- {
- if( ! writeBuffer( pFontData+nIndex, nNextSectionIndex - nIndex ) )
+ // now we can actually write the font stream !
+ #if OSL_DEBUG_LEVEL > 1
{
- endCompression();
- disableStreamEncryption();
- goto streamend;
+ OStringBuffer aLine( " PDFWriterImpl::emitEmbeddedFont" );
+ emitComment( aLine.getStr() );
}
- }
- // write following sections
- while( it != aSections.end() )
- {
- nIndex = (*it)+6;
- ++it;
- if( nIndex < nFontLen ) // last section marker is usually the EOF which has only 2 bytes
+ #endif
+ OStringBuffer aLine( 512 );
+ nStreamObject = createObject();
+ if( !updateObject(nStreamObject))
+ throw FontException();
+ sal_Int32 nStreamLengthObject = createObject();
+ aLine.append( nStreamObject );
+ aLine.append( " 0 obj\n"
+ "<</Length " );
+ aLine.append( nStreamLengthObject );
+ aLine.append( " 0 R"
+ #ifndef DEBUG_DISABLE_PDFCOMPRESSION
+ "/Filter/FlateDecode"
+ #endif
+ "/Length1 " );
+ aLine.append( nLength1 );
+ aLine.append( " /Length2 " );
+ aLine.append( nLength2 );
+ aLine.append( " /Length3 ");
+ aLine.append( nLength3 );
+ aLine.append( ">>\n"
+ "stream\n" );
+ if( !writeBuffer( aLine.getStr(), aLine.getLength() ) )
+ throw FontException();
+
+ sal_uInt64 nBeginStreamPos = 0;
+ osl_getFilePos( m_aFile, &nBeginStreamPos );
+
+ beginCompression();
+ checkAndEnableStreamEncryption( nStreamObject );
+
+ // write ascii section
+ if( aSections.begin() == aSections.end() )
+ {
+ if( ! writeBuffer( pFontData, nEndAsciiIndex+1 ) )
+ throw FontException();
+ }
+ else
{
- sal_Int32 nSectionLen = (it == aSections.end()) ? nFontLen - nIndex : (*it) - nIndex;
- if( ! writeBuffer( pFontData+nIndex, nSectionLen ) )
+ // first section always starts at 0
+ it = aSections.begin();
+ nIndex = (*it)+6;
+ ++it;
+ while( *it < nEndAsciiIndex )
{
- endCompression();
- disableStreamEncryption();
- goto streamend;
+ if( ! writeBuffer( pFontData+nIndex, (*it)-nIndex ) )
+ throw FontException();
+ nIndex = (*it)+6;
+ ++it;
}
+ // write partial last section
+ if( ! writeBuffer( pFontData+nIndex, nEndAsciiIndex-nIndex+1 ) )
+ throw FontException();
}
- }
- }
- }
- endCompression();
- disableStreamEncryption();
-
-
- sal_uInt64 nEndStreamPos = 0;
- osl_getFilePos( m_aFile, &nEndStreamPos );
- // and finally close the stream
- aLine.setLength( 0 );
- aLine.append( "\nendstream\nendobj\n\n" );
- if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
- goto streamend;
+ // write binary section
+ if( ! bConvertHexData )
+ {
+ if( aSections.begin() == aSections.end() )
+ {
+ if( ! writeBuffer( pFontData+nBeginBinaryIndex, nFontLen-nBeginBinaryIndex ) )
+ throw FontException();
+ }
+ else
+ {
+ for( it = aSections.begin(); *it < nBeginBinaryIndex; ++it )
+ ;
+ // write first partial section
+ if( ! writeBuffer( pFontData+nBeginBinaryIndex, (*it) - nBeginBinaryIndex ) )
+ throw FontException();
+ // write following sections
+ while( it != aSections.end() )
+ {
+ nIndex = (*it)+6;
+ ++it;
+ if( nIndex < nFontLen ) // last section marker is usually the EOF which has only 2 bytes
+ {
+ sal_Int32 nSectionLen = (it == aSections.end()) ? nFontLen - nIndex : (*it) - nIndex;
+ if( ! writeBuffer( pFontData+nIndex, nSectionLen ) )
+ throw FontException();
+ }
+ }
+ }
+ }
+ else
+ {
+ boost::shared_array<unsigned char> pWriteBuffer( new unsigned char[ nLength2 ] );
+ rtl_zeroMemory( pWriteBuffer.get(), nLength2 );
+ int nWriteIndex = 0;
+
+ int nNextSectionIndex = 0;
+ for( it = aSections.begin(); it != aSections.end() && *it < nBeginBinaryIndex; ++it )
+ ;
+ if( it != aSections.end() )
+ nNextSectionIndex = *it;
+ for( nIndex = nBeginBinaryIndex; nIndex <= nEndBinaryIndex; nIndex++ )
+ {
+ if( nIndex == nNextSectionIndex )
+ {
+ nIndex += 6;
+ ++it;
+ nNextSectionIndex = (it == aSections.end() ? nFontLen : *it );
+ }
+ unsigned char cNibble = 0x80;
+ if( pFontData[ nIndex ] >= '0' && pFontData[ nIndex ] <= '9' )
+ cNibble = pFontData[nIndex] - '0';
+ else if( pFontData[ nIndex ] >= 'a' && pFontData[ nIndex ] <= 'f' )
+ cNibble = pFontData[nIndex] - 'a' + 10;
+ else if( pFontData[ nIndex ] >= 'A' && pFontData[ nIndex ] <= 'F' )
+ cNibble = pFontData[nIndex] - 'A' + 10;
+ if( cNibble != 0x80 )
+ {
+ if( !(nWriteIndex & 1 ) )
+ cNibble <<= 4;
+ pWriteBuffer.get()[ nWriteIndex/2 ] |= cNibble;
+ nWriteIndex++;
+ }
+ }
+ if( ! writeBuffer( pWriteBuffer.get(), nLength2 ) )
+ throw FontException();
+ if( aSections.empty() )
+ {
+ if( ! writeBuffer( pFontData+nIndex, nFontLen-nIndex ) )
+ throw FontException();
+ }
+ else
+ {
+ // write rest of this section
+ if( nIndex < nNextSectionIndex )
+ {
+ if( ! writeBuffer( pFontData+nIndex, nNextSectionIndex - nIndex ) )
+ throw FontException();
+ }
+ // write following sections
+ while( it != aSections.end() )
+ {
+ nIndex = (*it)+6;
+ ++it;
+ if( nIndex < nFontLen ) // last section marker is usually the EOF which has only 2 bytes
+ {
+ sal_Int32 nSectionLen = (it == aSections.end()) ? nFontLen - nIndex : (*it) - nIndex;
+ if( ! writeBuffer( pFontData+nIndex, nSectionLen ) )
+ throw FontException();
+ }
+ }
+ }
+ }
+ endCompression();
+ disableStreamEncryption();
- // write stream length object
- aLine.setLength( 0 );
- if( ! updateObject( nStreamLengthObject ) )
- goto streamend;
- aLine.append( nStreamLengthObject );
- aLine.append( " 0 obj\n" );
- aLine.append( (sal_Int64)(nEndStreamPos-nBeginStreamPos ) );
- aLine.append( "\nendobj\n\n" );
- if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
- goto streamend;
- }
- else
- {
- rtl::OStringBuffer aErrorComment( 256 );
- aErrorComment.append( "GetEmbedFontData failed for font \"" );
- aErrorComment.append( OUStringToOString( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ) );
- aErrorComment.append( '\"' );
- if( pFont->GetSlant() == ITALIC_NORMAL )
- aErrorComment.append( " italic" );
- else if( pFont->GetSlant() == ITALIC_OBLIQUE )
- aErrorComment.append( " oblique" );
- aErrorComment.append( " weight=" );
- aErrorComment.append( sal_Int32(pFont->GetWeight()) );
- emitComment( aErrorComment.getStr() );
- }
-
- if( nStreamObject )
- // write font descriptor
- nFontDescriptor = emitFontDescriptor( pFont, aInfo, 0, nStreamObject );
- if( nFontDescriptor )
- {
- if( pEncoding )
- nToUnicodeStream = createToUnicodeCMap( nEncoding, nEncodedCodes, sizeof(nEncoding)/sizeof(nEncoding[0]) );
+ sal_uInt64 nEndStreamPos = 0;
+ osl_getFilePos( m_aFile, &nEndStreamPos );
- // write font object
- sal_Int32 nObject = createObject();
- if( ! updateObject( nObject ) )
- goto streamend;
+ // and finally close the stream
+ aLine.setLength( 0 );
+ aLine.append( "\nendstream\nendobj\n\n" );
+ if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
+ throw FontException();
- OStringBuffer aLine( 1024 );
- aLine.append( nObject );
- aLine.append( " 0 obj\n"
- "<</Type/Font/Subtype/Type1/BaseFont/" );
- appendName( aInfo.m_aPSName, aLine );
- aLine.append( "\n" );
- if( !pFont->mbSymbolFlag && pEncoding == 0 )
- aLine.append( "/Encoding/WinAnsiEncoding\n" );
- if( nToUnicodeStream )
- {
- aLine.append( "/ToUnicode " );
- aLine.append( nToUnicodeStream );
- aLine.append( " 0 R\n" );
+ // write stream length object
+ aLine.setLength( 0 );
+ if( ! updateObject( nStreamLengthObject ) )
+ throw FontException();
+ aLine.append( nStreamLengthObject );
+ aLine.append( " 0 obj\n" );
+ aLine.append( (sal_Int64)(nEndStreamPos-nBeginStreamPos ) );
+ aLine.append( "\nendobj\n\n" );
+ if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
+ throw FontException();
}
- aLine.append( "/FirstChar 0 /LastChar 255\n"
- "/Widths[" );
- for( int i = 0; i < 256; i++ )
+ else
{
- aLine.append( pWidths[i] );
- aLine.append( ((i&15) == 15) ? "\n" : " " );
- }
- aLine.append( "]\n"
- "/FontDescriptor " );
- aLine.append( nFontDescriptor );
- aLine.append( " 0 R>>\n"
- "endobj\n\n" );
- if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
- goto streamend;
-
- nFontObject = nObject;
-
- aRet[ rEmbed.m_nNormalFontID ] = nObject;
+ rtl::OStringBuffer aErrorComment( 256 );
+ aErrorComment.append( "GetEmbedFontData failed for font \"" );
+ aErrorComment.append( OUStringToOString( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ) );
+ aErrorComment.append( '\"' );
+ if( pFont->GetSlant() == ITALIC_NORMAL )
+ aErrorComment.append( " italic" );
+ else if( pFont->GetSlant() == ITALIC_OBLIQUE )
+ aErrorComment.append( " oblique" );
+ aErrorComment.append( " weight=" );
+ aErrorComment.append( sal_Int32(pFont->GetWeight()) );
+ emitComment( aErrorComment.getStr() );
+ }
+
+ if( nStreamObject )
+ // write font descriptor
+ nFontDescriptor = emitFontDescriptor( pFont, aInfo, 0, nStreamObject );
- // write additional encodings
- for( std::list< EmbedEncoding >::iterator enc_it = rEmbed.m_aExtendedEncodings.begin(); enc_it != rEmbed.m_aExtendedEncodings.end(); ++enc_it )
+ if( nFontDescriptor )
{
- sal_Int32 aEncWidths[ 256 ];
- // emit encoding dict
- sal_Int32 nEncObject = createObject();
- if( ! updateObject( nEncObject ) )
- goto streamend;
-
- OutputDevice* pRef = getReferenceDevice();
- pRef->Push( PUSH_FONT | PUSH_MAPMODE );
- pRef->SetMapMode( MapMode( MAP_PIXEL ) );
- Font aFont( pFont->GetFamilyName(), pFont->GetStyleName(), Size( 0, 1000 ) );
- aFont.SetWeight( pFont->GetWeight() );
- aFont.SetItalic( pFont->GetSlant() );
- aFont.SetPitch( pFont->GetPitch() );
- pRef->SetFont( aFont );
- pRef->ImplNewFont();
-
- aLine.setLength( 0 );
- aLine.append( nEncObject );
- aLine.append( " 0 obj\n"
- "<</Type/Encoding/Differences[ 0\n" );
- int nEncoded = 0;
- for( std::vector< EmbedCode >::iterator str_it = enc_it->m_aEncVector.begin(); str_it != enc_it->m_aEncVector.end(); ++str_it )
- {
- String aStr( str_it->m_aUnicode );
- aEncWidths[nEncoded] = pRef->GetTextWidth( aStr );
- nEncodedCodes[nEncoded] = str_it->m_aUnicode;
- nEncoding[nEncoded] = sal::static_int_cast<sal_uInt8>(nEncoded);
-
- aLine.append( " /" );
- aLine.append( str_it->m_aName );
- if( !((++nEncoded) & 15) )
- aLine.append( "\n" );
- }
- aLine.append( "]>>\n"
- "endobj\n\n" );
-
- pRef->Pop();
-
- if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
- goto streamend;
-
- nToUnicodeStream = createToUnicodeCMap( nEncoding, nEncodedCodes, nEncoded );
+ if( pEncoding )
+ nToUnicodeStream = createToUnicodeCMap( nEncoding, &aUnicodes[0], pUnicodesPerGlyph, pEncToUnicodeIndex, sizeof(nEncoding)/sizeof(nEncoding[0]) );
- nObject = createObject();
+ // write font object
+ sal_Int32 nObject = createObject();
if( ! updateObject( nObject ) )
- goto streamend;
+ throw FontException();
- aLine.setLength( 0 );
+ OStringBuffer aLine( 1024 );
aLine.append( nObject );
aLine.append( " 0 obj\n"
- "<</Type/Font/Subtype/Type1/BaseFont/" );
+ "<</Type/Font/Subtype/Type1/BaseFont/" );
appendName( aInfo.m_aPSName, aLine );
aLine.append( "\n" );
- aLine.append( "/Encoding " );
- aLine.append( nEncObject );
- aLine.append( " 0 R\n" );
+ if( !pFont->mbSymbolFlag && pEncoding == 0 )
+ aLine.append( "/Encoding/WinAnsiEncoding\n" );
if( nToUnicodeStream )
{
aLine.append( "/ToUnicode " );
aLine.append( nToUnicodeStream );
aLine.append( " 0 R\n" );
}
- aLine.append( "/FirstChar 0\n"
- "/LastChar " );
- aLine.append( (sal_Int32)(nEncoded-1) );
- aLine.append( "\n"
- "/Widths[" );
- for( int i = 0; i < nEncoded; i++ )
+ aLine.append( "/FirstChar 0 /LastChar 255\n"
+ "/Widths[" );
+ for( int i = 0; i < 256; i++ )
{
- aLine.append( aEncWidths[i] );
+ aLine.append( pWidths[i] );
aLine.append( ((i&15) == 15) ? "\n" : " " );
}
- aLine.append( " ]\n"
- "/FontDescriptor " );
+ aLine.append( "]\n"
+ "/FontDescriptor " );
aLine.append( nFontDescriptor );
aLine.append( " 0 R>>\n"
- "endobj\n\n" );
+ "endobj\n\n" );
if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
- goto streamend;
+ throw FontException();
- aRet[ enc_it->m_nFontID ] = nObject;
+ nFontObject = nObject;
+
+ aRet[ rEmbed.m_nNormalFontID ] = nObject;
+
+ // write additional encodings
+ for( std::list< EmbedEncoding >::iterator enc_it = rEmbed.m_aExtendedEncodings.begin(); enc_it != rEmbed.m_aExtendedEncodings.end(); ++enc_it )
+ {
+ sal_Int32 aEncWidths[ 256 ];
+ // emit encoding dict
+ sal_Int32 nEncObject = createObject();
+ if( ! updateObject( nEncObject ) )
+ throw FontException();
+
+ OutputDevice* pRef = getReferenceDevice();
+ pRef->Push( PUSH_FONT | PUSH_MAPMODE );
+ pRef->SetMapMode( MapMode( MAP_PIXEL ) );
+ Font aFont( pFont->GetFamilyName(), pFont->GetStyleName(), Size( 0, 1000 ) );
+ aFont.SetWeight( pFont->GetWeight() );
+ aFont.SetItalic( pFont->GetSlant() );
+ aFont.SetPitch( pFont->GetPitch() );
+ pRef->SetFont( aFont );
+ pRef->ImplNewFont();
+
+ aLine.setLength( 0 );
+ aLine.append( nEncObject );
+ aLine.append( " 0 obj\n"
+ "<</Type/Encoding/Differences[ 0\n" );
+ int nEncoded = 0;
+ aUnicodes.clear();
+ for( std::vector< EmbedCode >::iterator str_it = enc_it->m_aEncVector.begin(); str_it != enc_it->m_aEncVector.end(); ++str_it )
+ {
+ String aStr( str_it->m_aUnicode );
+ aEncWidths[nEncoded] = pRef->GetTextWidth( aStr );
+ nEncodedCodes[nEncoded] = str_it->m_aUnicode;
+ nEncoding[nEncoded] = sal::static_int_cast<sal_uInt8>(nEncoded);
+ pEncToUnicodeIndex[nEncoded] = static_cast<sal_Int32>(aUnicodes.size());
+ aUnicodes.push_back( nEncodedCodes[nEncoded] );
+ pUnicodesPerGlyph[nEncoded] = 1;
+
+ aLine.append( " /" );
+ aLine.append( str_it->m_aName );
+ if( !((++nEncoded) & 15) )
+ aLine.append( "\n" );
+ }
+ aLine.append( "]>>\n"
+ "endobj\n\n" );
+
+ pRef->Pop();
+
+ if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
+ throw FontException();
+
+ nToUnicodeStream = createToUnicodeCMap( nEncoding, &aUnicodes[0], pUnicodesPerGlyph, pEncToUnicodeIndex, nEncoded );
+
+ nObject = createObject();
+ if( ! updateObject( nObject ) )
+ throw FontException();
+
+ aLine.setLength( 0 );
+ aLine.append( nObject );
+ aLine.append( " 0 obj\n"
+ "<</Type/Font/Subtype/Type1/BaseFont/" );
+ appendName( aInfo.m_aPSName, aLine );
+ aLine.append( "\n" );
+ aLine.append( "/Encoding " );
+ aLine.append( nEncObject );
+ aLine.append( " 0 R\n" );
+ if( nToUnicodeStream )
+ {
+ aLine.append( "/ToUnicode " );
+ aLine.append( nToUnicodeStream );
+ aLine.append( " 0 R\n" );
+ }
+ aLine.append( "/FirstChar 0\n"
+ "/LastChar " );
+ aLine.append( (sal_Int32)(nEncoded-1) );
+ aLine.append( "\n"
+ "/Widths[" );
+ for( int i = 0; i < nEncoded; i++ )
+ {
+ aLine.append( aEncWidths[i] );
+ aLine.append( ((i&15) == 15) ? "\n" : " " );
+ }
+ aLine.append( " ]\n"
+ "/FontDescriptor " );
+ aLine.append( nFontDescriptor );
+ aLine.append( " 0 R>>\n"
+ "endobj\n\n" );
+ if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) )
+ throw FontException();
+
+ aRet[ enc_it->m_nFontID ] = nObject;
+ }
}
}
+ catch( FontException& )
+ {
+ // these do nothing in case there was no compression or encryption ongoing
+ endCompression();
+ disableStreamEncryption();
+ }
- streamend:
if( pFontData )
m_pReferenceDevice->mpGraphics->FreeEmbedFontData( pFontData, nFontLen );
@@ -3567,11 +3552,15 @@ static void appendSubsetName( int nSubsetID, const OUString& rPSName, OStringBuf
appendName( rPSName, rBuffer );
}
-sal_Int32 PDFWriterImpl::createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUnicodes, int nGlyphs )
+sal_Int32 PDFWriterImpl::createToUnicodeCMap( sal_uInt8* pEncoding,
+ sal_Ucs* pUnicodes,
+ sal_Int32* pUnicodesPerGlyph,
+ sal_Int32* pEncToUnicodeIndex,
+ int nGlyphs )
{
int nMapped = 0, n = 0;
for( n = 0; n < nGlyphs; n++ )
- if( pUnicodes[n] )
+ if( pUnicodes[pEncToUnicodeIndex[n]] && pUnicodesPerGlyph[n] )
nMapped++;
if( nMapped == 0 )
@@ -3599,7 +3588,7 @@ sal_Int32 PDFWriterImpl::createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUn
int nCount = 0;
for( n = 0; n < nGlyphs; n++ )
{
- if( pUnicodes[n] )
+ if( pUnicodes[pEncToUnicodeIndex[n]] && pUnicodesPerGlyph[n] )
{
if( (nCount % 100) == 0 )
{
@@ -3611,9 +3600,13 @@ sal_Int32 PDFWriterImpl::createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUn
aContents.append( '<' );
appendHex( (sal_Int8)pEncoding[n], aContents );
aContents.append( "> <" );
- // TODO: handle unicodes>U+FFFF
- appendHex( (sal_Int8)(pUnicodes[n] / 256), aContents );
- appendHex( (sal_Int8)(pUnicodes[n] & 255), aContents );
+ // TODO: handle unicodes>U+FFFF
+ sal_Int32 nIndex = pEncToUnicodeIndex[n];
+ for( sal_Int32 j = 0; j < pUnicodesPerGlyph[n]; j++ )
+ {
+ appendHex( (sal_Int8)(pUnicodes[nIndex + j] / 256), aContents );
+ appendHex( (sal_Int8)(pUnicodes[nIndex + j] & 255), aContents );
+ }
aContents.append( ">\n" );
nCount++;
}
@@ -3777,25 +3770,32 @@ bool PDFWriterImpl::emitFonts()
sal_Int32 pGlyphIDs[ 256 ];
sal_Int32 pWidths[ 256 ];
sal_uInt8 pEncoding[ 256 ];
- sal_Ucs pUnicodes[ 256 ];
+ sal_Int32 pEncToUnicodeIndex[ 256 ];
+ sal_Int32 pUnicodesPerGlyph[ 256 ];
+ std::vector<sal_Ucs> aUnicodes;
+ aUnicodes.reserve( 256 );
int nGlyphs = 1;
// fill arrays and prepare encoding index map
sal_Int32 nToUnicodeStream = 0;
- memset( pGlyphIDs, 0, sizeof( pGlyphIDs ) );
- memset( pEncoding, 0, sizeof( pEncoding ) );
- memset( pUnicodes, 0, sizeof( pUnicodes ) );
+ rtl_zeroMemory( pGlyphIDs, sizeof( pGlyphIDs ) );
+ rtl_zeroMemory( pEncoding, sizeof( pEncoding ) );
+ rtl_zeroMemory( pUnicodesPerGlyph, sizeof( pUnicodesPerGlyph ) );
+ rtl_zeroMemory( pEncToUnicodeIndex, sizeof( pEncToUnicodeIndex ) );
for( FontEmitMapping::iterator fit = lit->m_aMapping.begin(); fit != lit->m_aMapping.end();++fit )
{
- sal_uInt8 nEnc = fit->second.m_nSubsetGlyphID;
+ sal_uInt8 nEnc = fit->second.getGlyphId();
DBG_ASSERT( pGlyphIDs[nEnc] == 0 && pEncoding[nEnc] == 0, "duplicate glyph" );
DBG_ASSERT( nEnc <= lit->m_aMapping.size(), "invalid glyph encoding" );
pGlyphIDs[ nEnc ] = fit->first;
pEncoding[ nEnc ] = nEnc;
- pUnicodes[ nEnc ] = fit->second.m_aUnicode;
- if( pUnicodes[ nEnc ] )
+ pEncToUnicodeIndex[ nEnc ] = static_cast<sal_Int32>(aUnicodes.size());
+ pUnicodesPerGlyph[ nEnc ] = fit->second.countCodes();
+ for( sal_Int32 n = 0; n < pUnicodesPerGlyph[ nEnc ]; n++ )
+ aUnicodes.push_back( fit->second.getCode( n ) );
+ if( fit->second.getCode(0) )
nToUnicodeStream = 1;
if( nGlyphs < 256 )
nGlyphs++;
@@ -3816,92 +3816,92 @@ bool PDFWriterImpl::emitFonts()
CHECK_RETURN( (osl_File_E_None == osl_getFilePos( aFontFile, &nLength1 ) ) );
CHECK_RETURN( (osl_File_E_None == osl_setFilePos( aFontFile, osl_Pos_Absolut, 0 ) ) );
-#if OSL_DEBUG_LEVEL > 1
+ #if OSL_DEBUG_LEVEL > 1
{
OStringBuffer aLine1( " PDFWriterImpl::emitFonts" );
emitComment( aLine1.getStr() );
}
-#endif
+ #endif
sal_Int32 nFontStream = createObject();
sal_Int32 nStreamLengthObject = createObject();
CHECK_RETURN( updateObject( nFontStream ) );
aLine.setLength( 0 );
aLine.append( nFontStream );
aLine.append( " 0 obj\n"
- "<</Length " );
+ "<</Length " );
aLine.append( (sal_Int32)nStreamLengthObject );
aLine.append( " 0 R"
-#ifndef DEBUG_DISABLE_PDFCOMPRESSION
- "/Filter/FlateDecode"
-#endif
- "/Length1 " );
-
- sal_uInt64 nStartPos = 0;
- if( aSubsetInfo.m_nFontType == FontSubsetInfo::SFNT_TTF )
- {
- aLine.append( (sal_Int32)nLength1 );
+ #ifndef DEBUG_DISABLE_PDFCOMPRESSION
+ "/Filter/FlateDecode"
+ #endif
+ "/Length1 " );
- aLine.append( ">>\n"
- "stream\n" );
- CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) );
- CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nStartPos ) ) );
-
- // copy font file
- beginCompression();
- checkAndEnableStreamEncryption( nFontStream );
- sal_Bool bEOF = sal_False;
- do
+ sal_uInt64 nStartPos = 0;
+ if( aSubsetInfo.m_nFontType == FontSubsetInfo::SFNT_TTF )
{
- char buf[8192];
- sal_uInt64 nRead;
- CHECK_RETURN( (osl_File_E_None == osl_readFile( aFontFile, buf, sizeof( buf ), &nRead ) ) );
- CHECK_RETURN( writeBuffer( buf, nRead ) );
- CHECK_RETURN( (osl_File_E_None == osl_isEndOfFile( aFontFile, &bEOF ) ) );
- } while( ! bEOF );
- }
- else if( (aSubsetInfo.m_nFontType & FontSubsetInfo::CFF_FONT) != 0 )
- {
- // TODO: implement
- DBG_ERROR( "PDFWriterImpl does not support CFF-font subsets yet!" );
- }
- else if( (aSubsetInfo.m_nFontType & FontSubsetInfo::TYPE1_PFB) != 0 ) // TODO: also support PFA?
- {
- unsigned char* pBuffer = new unsigned char[ (int)nLength1 ];
-
- sal_uInt64 nBytesRead = 0;
- CHECK_RETURN( (osl_File_E_None == osl_readFile( aFontFile, pBuffer, nLength1, &nBytesRead ) ) );
- DBG_ASSERT( nBytesRead==nLength1, "PDF-FontSubset read incomplete!" );
- CHECK_RETURN( (osl_File_E_None == osl_setFilePos( aFontFile, osl_Pos_Absolut, 0 ) ) );
- // get the PFB-segment lengths
- ThreeInts aSegmentLengths = {0,0,0};
- getPfbSegmentLengths( pBuffer, (int)nBytesRead, aSegmentLengths );
- // the lengths below are mandatory for PDF-exported Type1 fonts
- // because the PFB segment headers get stripped! WhyOhWhy.
- aLine.append( (sal_Int32)aSegmentLengths[0] );
- aLine.append( "/Length2 " );
- aLine.append( (sal_Int32)aSegmentLengths[1] );
- aLine.append( "/Length3 " );
- aLine.append( (sal_Int32)aSegmentLengths[2] );
-
- aLine.append( ">>\n"
- "stream\n" );
- CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) );
- CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nStartPos ) ) );
-
- // emit PFB-sections without section headers
- beginCompression();
- checkAndEnableStreamEncryption( nFontStream );
- CHECK_RETURN( writeBuffer( pBuffer+ 6, aSegmentLengths[0] ) );
- CHECK_RETURN( writeBuffer( pBuffer+12 + aSegmentLengths[0], aSegmentLengths[1] ) );
- CHECK_RETURN( writeBuffer( pBuffer+18 + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) );
-
- delete[] pBuffer;
- }
- else
- {
- fprintf( stderr, "PDF: CreateFontSubset result in not yet supported format=%d\n",aSubsetInfo.m_nFontType);
- aLine.append( "0 >>\nstream\n" );
- }
+ aLine.append( (sal_Int32)nLength1 );
+
+ aLine.append( ">>\n"
+ "stream\n" );
+ CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) );
+ CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nStartPos ) ) );
+
+ // copy font file
+ beginCompression();
+ checkAndEnableStreamEncryption( nFontStream );
+ sal_Bool bEOF = sal_False;
+ do
+ {
+ char buf[8192];
+ sal_uInt64 nRead;
+ CHECK_RETURN( (osl_File_E_None == osl_readFile( aFontFile, buf, sizeof( buf ), &nRead ) ) );
+ CHECK_RETURN( writeBuffer( buf, nRead ) );
+ CHECK_RETURN( (osl_File_E_None == osl_isEndOfFile( aFontFile, &bEOF ) ) );
+ } while( ! bEOF );
+ }
+ else if( (aSubsetInfo.m_nFontType & FontSubsetInfo::CFF_FONT) != 0 )
+ {
+ // TODO: implement
+ DBG_ERROR( "PDFWriterImpl does not support CFF-font subsets yet!" );
+ }
+ else if( (aSubsetInfo.m_nFontType & FontSubsetInfo::TYPE1_PFB) != 0 ) // TODO: also support PFA?
+ {
+ unsigned char* pBuffer = new unsigned char[ (int)nLength1 ];
+
+ sal_uInt64 nBytesRead = 0;
+ CHECK_RETURN( (osl_File_E_None == osl_readFile( aFontFile, pBuffer, nLength1, &nBytesRead ) ) );
+ DBG_ASSERT( nBytesRead==nLength1, "PDF-FontSubset read incomplete!" );
+ CHECK_RETURN( (osl_File_E_None == osl_setFilePos( aFontFile, osl_Pos_Absolut, 0 ) ) );
+ // get the PFB-segment lengths
+ ThreeInts aSegmentLengths = {0,0,0};
+ getPfbSegmentLengths( pBuffer, (int)nBytesRead, aSegmentLengths );
+ // the lengths below are mandatory for PDF-exported Type1 fonts
+ // because the PFB segment headers get stripped! WhyOhWhy.
+ aLine.append( (sal_Int32)aSegmentLengths[0] );
+ aLine.append( "/Length2 " );
+ aLine.append( (sal_Int32)aSegmentLengths[1] );
+ aLine.append( "/Length3 " );
+ aLine.append( (sal_Int32)aSegmentLengths[2] );
+
+ aLine.append( ">>\n"
+ "stream\n" );
+ CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) );
+ CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nStartPos ) ) );
+
+ // emit PFB-sections without section headers
+ beginCompression();
+ checkAndEnableStreamEncryption( nFontStream );
+ CHECK_RETURN( writeBuffer( pBuffer+ 6, aSegmentLengths[0] ) );
+ CHECK_RETURN( writeBuffer( pBuffer+12 + aSegmentLengths[0], aSegmentLengths[1] ) );
+ CHECK_RETURN( writeBuffer( pBuffer+18 + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) );
+
+ delete[] pBuffer;
+ }
+ else
+ {
+ fprintf( stderr, "PDF: CreateFontSubset result in not yet supported format=%d\n",aSubsetInfo.m_nFontType);
+ aLine.append( "0 >>\nstream\n" );
+ }
endCompression();
disableStreamEncryption();
@@ -3928,7 +3928,7 @@ bool PDFWriterImpl::emitFonts()
sal_Int32 nFontDescriptor = emitFontDescriptor( it->first, aSubsetInfo, lit->m_nFontID, nFontStream );
if( nToUnicodeStream )
- nToUnicodeStream = createToUnicodeCMap( pEncoding, pUnicodes, nGlyphs );
+ nToUnicodeStream = createToUnicodeCMap( pEncoding, &aUnicodes[0], pUnicodesPerGlyph, pEncToUnicodeIndex, nGlyphs );
sal_Int32 nFontObject = createObject();
CHECK_RETURN( updateObject( nFontObject ) );
@@ -3937,22 +3937,22 @@ bool PDFWriterImpl::emitFonts()
aLine.append( " 0 obj\n" );
aLine.append( ((aSubsetInfo.m_nFontType & FontSubsetInfo::ANY_TYPE1) != 0) ?
- "<</Type/Font/Subtype/Type1/BaseFont/" :
- "<</Type/Font/Subtype/TrueType/BaseFont/" );
+ "<</Type/Font/Subtype/Type1/BaseFont/" :
+ "<</Type/Font/Subtype/TrueType/BaseFont/" );
appendSubsetName( lit->m_nFontID, aSubsetInfo.m_aPSName, aLine );
aLine.append( "\n"
- "/FirstChar 0\n"
- "/LastChar " );
+ "/FirstChar 0\n"
+ "/LastChar " );
aLine.append( (sal_Int32)(nGlyphs-1) );
aLine.append( "\n"
- "/Widths[" );
+ "/Widths[" );
for( int i = 0; i < nGlyphs; i++ )
{
aLine.append( pWidths[ i ] );
aLine.append( ((i & 15) == 15) ? "\n" : " " );
}
aLine.append( "]\n"
- "/FontDescriptor " );
+ "/FontDescriptor " );
aLine.append( nFontDescriptor );
aLine.append( " 0 R\n" );
if( nToUnicodeStream )
@@ -3962,7 +3962,7 @@ bool PDFWriterImpl::emitFonts()
aLine.append( " 0 R\n" );
}
aLine.append( ">>\n"
- "endobj\n\n" );
+ "endobj\n\n" );
CHECK_RETURN( writeBuffer( aLine.getStr(), aLine.getLength() ) );
aFontIDToObject[ lit->m_nFontID ] = nFontObject;
@@ -4011,7 +4011,7 @@ bool PDFWriterImpl::emitFonts()
OStringBuffer aFontDict( 1024 );
aFontDict.append( getFontDictObject() );
aFontDict.append( " 0 obj\n"
- "<<" );
+ "<<" );
int ni = 0;
for( std::map< sal_Int32, sal_Int32 >::iterator mit = aFontIDToObject.begin(); mit != aFontIDToObject.end(); ++mit )
{
@@ -4020,12 +4020,12 @@ bool PDFWriterImpl::emitFonts()
aFontDict.append( ' ' );
aFontDict.append( mit->second );
aFontDict.append( " 0 R" );
- if( ((++ni) & 7) == 0 )
- aFontDict.append( '\n' );
+ if( ((++ni) & 7) == 0 )
+ aFontDict.append( '\n' );
}
// emit builtin font for widget apperances / variable text
for( std::map< sal_Int32, sal_Int32 >::iterator it = m_aBuiltinFontToObjectMap.begin();
- it != m_aBuiltinFontToObjectMap.end(); ++it )
+ it != m_aBuiltinFontToObjectMap.end(); ++it )
{
ImplPdfBuiltinFontData aData(m_aBuiltinFonts[it->first]);
it->second = emitBuiltinFont( &aData, it->second );
@@ -6580,12 +6580,14 @@ void PDFWriterImpl::registerGlyphs( int nGlyphs,
sal_GlyphId* pGlyphs,
sal_Int32* pGlyphWidths,
sal_Ucs* pUnicodes,
+ sal_Int32* pUnicodesPerGlyph,
sal_uInt8* pMappedGlyphs,
sal_Int32* pMappedFontObjects,
const ImplFontData* pFallbackFonts[] )
{
const ImplFontData* pDevFont = m_pReferenceDevice->mpFontEntry->maFontSelData.mpFontData;
- for( int i = 0; i < nGlyphs; i++ )
+ sal_Ucs* pCurUnicode = pUnicodes;
+ for( int i = 0; i < nGlyphs; pCurUnicode += pUnicodesPerGlyph[i] , i++ )
{
const int nFontGlyphId = pGlyphs[i] & (GF_IDXMASK | GF_ISCHAR | GF_GSUB);
const ImplFontData* pCurrentFont = pFallbackFonts[i] ? pFallbackFonts[i] : pDevFont;
@@ -6640,8 +6642,9 @@ void PDFWriterImpl::registerGlyphs( int nGlyphs,
// add new glyph to emitted font subset
GlyphEmit& rNewGlyphEmit = rSubset.m_aSubsets.back().m_aMapping[ nFontGlyphId ];
- rNewGlyphEmit.m_nSubsetGlyphID = nNewId;
- rNewGlyphEmit.m_aUnicode = (pUnicodes ? pUnicodes[i] : 0);
+ rNewGlyphEmit.setGlyphId( nNewId );
+ for( sal_Int32 n = 0; n < pUnicodesPerGlyph[i]; n++ )
+ rNewGlyphEmit.addCode( pCurUnicode[n] );
// add new glyph to font mapping
Glyph& rNewGlyph = rSubset.m_aMapping[ nFontGlyphId ];
@@ -6678,7 +6681,7 @@ void PDFWriterImpl::registerGlyphs( int nGlyphs,
Ucs2OStrMap::const_iterator nonenc_it;
sal_Int32 nCurFontID = nFontID;
- sal_Ucs cChar = pUnicodes[i];
+ sal_Ucs cChar = *pCurUnicode;
if( pEncoding )
{
enc_it = pEncoding->find( cChar );
@@ -6740,7 +6743,7 @@ void PDFWriterImpl::registerGlyphs( int nGlyphs,
pMappedGlyphs[ i ] = (sal_Int8)cChar;
pMappedFontObjects[ i ] = nCurFontID;
pGlyphWidths[ i ] = m_aFontCache.getGlyphWidth( pCurrentFont,
- (pEncoding ? pUnicodes[i] : cChar) | GF_ISCHAR,
+ (pEncoding ? *pCurUnicode : cChar) | GF_ISCHAR,
false,
m_pReferenceDevice->mpGraphics );
}
@@ -7020,7 +7023,9 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT
sal_Int32 pGlyphWidths[nMaxGlyphs];
sal_uInt8 pMappedGlyphs[nMaxGlyphs];
sal_Int32 pMappedFontObjects[nMaxGlyphs];
- sal_Ucs pUnicodes[nMaxGlyphs];
+ std::vector<sal_Ucs> aUnicodes;
+ aUnicodes.reserve( nMaxGlyphs );
+ sal_Int32 pUnicodesPerGlyph[nMaxGlyphs];
int pCharPosAry[nMaxGlyphs];
sal_Int32 nAdvanceWidths[nMaxGlyphs];
const ImplFontData* pFallbackFonts[nMaxGlyphs];
@@ -7153,15 +7158,29 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT
Point aGNGlyphPos;
while( (nGlyphs = rLayout.GetNextGlyphs( nTmpMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, nAdvanceWidths, pCharPosAry )) != 0 )
{
+ aUnicodes.clear();
for( int i = 0; i < nGlyphs; i++ )
{
pFallbackFonts[i] = rLayout.GetFallbackFontData( pGlyphs[i] );
+ // default case: 1 glyph is one unicode
+ pUnicodesPerGlyph[i] = 1;
if( (pGlyphs[i] & GF_ISCHAR) )
- pUnicodes[i] = static_cast<sal_Ucs>(pGlyphs[i] & GF_IDXMASK);
+ {
+ aUnicodes.push_back( static_cast<sal_Ucs>(pGlyphs[i] & GF_IDXMASK) );
+ }
else if( pCharPosAry[i] >= nMinCharPos && pCharPosAry[i] <= nMaxCharPos )
{
- pUnicodes[i] = rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]) );
+ int nChars = 1;
+ aUnicodes.push_back( rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]) ) );
+ pUnicodesPerGlyph[i] = 1;
+ // try to handle ligatures and such
+ if( i < nGlyphs-1 )
+ {
+ pUnicodesPerGlyph[i] = nChars = pCharPosAry[i+1] - pCharPosAry[i];
+ for( int n = 1; n < nChars; n++ )
+ aUnicodes.push_back( rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]+n) ) );
+ }
// #i36691# hack that is needed because currently the pGlyphs[]
// argument is ignored for embeddable fonts and so the layout
// engine's glyph work is ignored (i.e. char mirroring)
@@ -7169,17 +7188,21 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT
// glyphid (i.e. FreeType's synthetic glyphid for a Type1 font)
// back to unicode and then to embeddable font's encoding
if( getReferenceDevice()->GetLayoutMode() & TEXT_LAYOUT_BIDI_RTL )
- pUnicodes[i] = static_cast<sal_Ucs>(GetMirroredChar(pUnicodes[i]));
+ {
+ size_t nI = aUnicodes.size()-1;
+ for( int n = 0; n < nChars; n++, nI-- )
+ aUnicodes[nI] = static_cast<sal_Ucs>(GetMirroredChar(aUnicodes[nI]));
+ }
}
else
- pUnicodes[i] = 0;
+ aUnicodes.push_back( 0 );
// note: in case of ctl one character may result
// in multiple glyphs. The current SalLayout
// implementations set -1 then to indicate that no direct
// mapping is possible
}
- registerGlyphs( nGlyphs, pGlyphs, pGlyphWidths, pUnicodes, pMappedGlyphs, pMappedFontObjects, pFallbackFonts );
+ registerGlyphs( nGlyphs, pGlyphs, pGlyphWidths, &aUnicodes[0], pUnicodesPerGlyph, pMappedGlyphs, pMappedFontObjects, pFallbackFonts );
for( int i = 0; i < nGlyphs; i++ )
{
@@ -9513,7 +9536,7 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
sal_uInt64 nStartPos = 0;
CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nStartPos )) );
- checkAndEnableStreamEncryption( rObject.m_nObject );
+ checkAndEnableStreamEncryption( rObject.m_nObject );
beginCompression();
if( ! bTrueColor || pAccess->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
{
@@ -9527,7 +9550,7 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
else
{
const int nScanLineBytes = pAccess->Width()*3;
- sal_uInt8 *pCol = (sal_uInt8*)rtl_allocateMemory( nScanLineBytes );
+ boost::shared_array<sal_uInt8> pCol( new sal_uInt8[ nScanLineBytes ] );
for( int y = 0; y < pAccess->Height(); y++ )
{
for( int x = 0; x < pAccess->Width(); x++ )
@@ -9537,9 +9560,8 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask )
pCol[3*x+1] = aColor.GetGreen();
pCol[3*x+2] = aColor.GetBlue();
}
- CHECK_RETURN( writeBuffer( pCol, nScanLineBytes ) );
+ CHECK_RETURN( writeBuffer( pCol.get(), nScanLineBytes ) );
}
- rtl_freeMemory( pCol );
}
endCompression();
disableStreamEncryption();
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index e058cfa487db..d54aecf35788 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -52,6 +52,8 @@
#include <hash_map>
#include <list>
+#include <boost/shared_array.hpp>
+
class ImplFontSelectData;
class ImplFontMetricData;
class FontSubsetInfo;
@@ -270,10 +272,53 @@ public:
};
// font subsets
- struct GlyphEmit
+ class GlyphEmit
{
- sal_Ucs m_aUnicode;
- sal_uInt8 m_nSubsetGlyphID;
+ // performance: actually this should probably a vector;
+ sal_Ucs m_aBufferedUnicodes[3];
+ sal_Int32 m_nUnicodes;
+ sal_Int32 m_nMaxUnicodes;
+ boost::shared_array<sal_Ucs> m_pUnicodes;
+ sal_uInt8 m_nSubsetGlyphID;
+
+ public:
+ GlyphEmit() : m_nUnicodes(0), m_nSubsetGlyphID(0)
+ {
+ rtl_zeroMemory( m_aBufferedUnicodes, sizeof( m_aBufferedUnicodes ) );
+ m_nMaxUnicodes = sizeof(m_aBufferedUnicodes)/sizeof(m_aBufferedUnicodes[0]);
+ }
+ ~GlyphEmit()
+ {
+ }
+
+ void setGlyphId( sal_uInt8 i_nId ) { m_nSubsetGlyphID = i_nId; }
+ sal_uInt8 getGlyphId() const { return m_nSubsetGlyphID; }
+
+ void addCode( sal_Ucs i_cCode )
+ {
+ if( m_nUnicodes == m_nMaxUnicodes )
+ {
+ sal_Ucs* pNew = new sal_Ucs[ 2 * m_nMaxUnicodes];
+ if( m_pUnicodes.get() )
+ rtl_copyMemory( pNew, m_pUnicodes.get(), m_nMaxUnicodes * sizeof(sal_Ucs) );
+ else
+ rtl_copyMemory( pNew, m_aBufferedUnicodes, m_nMaxUnicodes * sizeof(sal_Ucs) );
+ m_pUnicodes.reset( pNew );
+ m_nMaxUnicodes *= 2;
+ }
+ if( m_pUnicodes.get() )
+ m_pUnicodes[ m_nUnicodes++ ] = i_cCode;
+ else
+ m_aBufferedUnicodes[ m_nUnicodes++ ] = i_cCode;
+ }
+ sal_Int32 countCodes() const { return m_nUnicodes; }
+ sal_Ucs getCode( sal_Int32 i_nIndex ) const
+ {
+ sal_Ucs nRet = 0;
+ if( i_nIndex < m_nUnicodes )
+ nRet = m_pUnicodes.get() ? m_pUnicodes[ i_nIndex ] : m_aBufferedUnicodes[ i_nIndex ];
+ return nRet;
+ }
};
typedef std::map< sal_GlyphId, GlyphEmit > FontEmitMapping;
struct FontEmit
@@ -860,7 +905,7 @@ i12626
void appendLiteralStringEncrypt( rtl::OStringBuffer& rInString, const sal_Int32 nInObjectNumber, rtl::OStringBuffer& rOutBuffer );
/* creates fonts and subsets that will be emitted later */
- void registerGlyphs( int nGlyphs, sal_GlyphId* pGlyphs, sal_Int32* pGlpyhWidths, sal_Ucs* pUnicodes, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, const ImplFontData* pFallbackFonts[] );
+ void registerGlyphs( int nGlyphs, sal_GlyphId* pGlyphs, sal_Int32* pGlpyhWidths, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_uInt8* pMappedGlyphs, sal_Int32* pMappedFontObjects, const ImplFontData* pFallbackFonts[] );
/* emits a text object according to the passed layout */
/* TODO: remove rText as soon as SalLayout will change so that rText is not necessary anymore */
@@ -909,7 +954,7 @@ i12626
/* writes a font descriptor and returns its object id (or 0) */
sal_Int32 emitFontDescriptor( const ImplFontData*, FontSubsetInfo&, sal_Int32 nSubsetID, sal_Int32 nStream );
/* writes a ToUnicode cmap, returns the corresponding stream object */
- sal_Int32 createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUnicodes, int nGlyphs );
+ sal_Int32 createToUnicodeCMap( sal_uInt8* pEncoding, sal_Ucs* pUnicodes, sal_Int32* pUnicodesPerGlyph, sal_Int32* pEncToUnicodeIndex, int nGlyphs );
/* get resource dict object number */
sal_Int32 getResourceDictObj()
diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx
index b92bea929c51..b25b9cee83fb 100644
--- a/vcl/source/glyphs/gcach_ftyp.cxx
+++ b/vcl/source/glyphs/gcach_ftyp.cxx
@@ -2486,14 +2486,12 @@ bool FreetypeServerFont::ApplyGSUB( const ImplFontSelectData& rFSD )
pCoverage += 2;
for( int i = nCntRange; --i >= 0; )
{
- const USHORT nGlyph0 = GetUShort( pCoverage+0 );
- const USHORT nGlyph1 = GetUShort( pCoverage+2 );
- const USHORT nStartCoverageIndex = GetUShort( pCoverage+4 );
- DBG_ASSERT( aSubstVector.size() == nStartCoverageIndex, "coverage index mismatch");
- (void)nStartCoverageIndex;
+ const UINT32 nGlyph0 = GetUShort( pCoverage+0 );
+ const UINT32 nGlyph1 = GetUShort( pCoverage+2 );
+ const USHORT nCovIdx = GetUShort( pCoverage+4 );
pCoverage += 6;
- for( USHORT j = nGlyph0; j <= nGlyph1; ++j )
- aSubstVector.push_back( GlyphSubst( j, 0 ) );
+ for( UINT32 j = nGlyph0; j <= nGlyph1; ++j )
+ aSubstVector.push_back( GlyphSubst( static_cast<USHORT>(j + nCovIdx), 0 ) );
}
}
break;
@@ -2537,3 +2535,4 @@ bool FreetypeServerFont::ApplyGSUB( const ImplFontSelectData& rFSD )
}
// =======================================================================
+
diff --git a/vcl/source/glyphs/graphite_adaptors.cxx b/vcl/source/glyphs/graphite_adaptors.cxx
index 34e2f5f5bbe3..6c9d97e356b1 100644
--- a/vcl/source/glyphs/graphite_adaptors.cxx
+++ b/vcl/source/glyphs/graphite_adaptors.cxx
@@ -171,7 +171,7 @@ GraphiteFontAdaptor::~GraphiteFontAdaptor() throw()
mpFeatures = NULL;
}
-void GraphiteFontAdaptor::UniqueCacheInfo(std::wstring & face_name_out, bool & bold_out, bool & italic_out)
+void GraphiteFontAdaptor::UniqueCacheInfo(sil_std::wstring & face_name_out, bool & bold_out, bool & italic_out)
{
face_name_out = maFontProperties.szFaceName;
bold_out = maFontProperties.fBold;
diff --git a/vcl/source/glyphs/graphite_cache.cxx b/vcl/source/glyphs/graphite_cache.cxx
index 8c514c611d2c..a2c245e21774 100644
--- a/vcl/source/glyphs/graphite_cache.cxx
+++ b/vcl/source/glyphs/graphite_cache.cxx
@@ -36,8 +36,10 @@
#include <tools/debug.hxx>
#include <vcl/sallayout.hxx>
+#include "pregraphitestl.h"
#include <graphite/GrClient.h>
#include <graphite/Segment.h>
+#include "postgraphitestl.h"
#include <rtl/ustring.hxx>
#include <vcl/graphite_layout.hxx>
diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx
index dae1bfc2866e..b26397aa43e5 100644
--- a/vcl/source/glyphs/graphite_features.cxx
+++ b/vcl/source/glyphs/graphite_features.cxx
@@ -91,7 +91,7 @@ GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string features, co
gr::isocode aLang = maLang;
for (size_t i = pos; i < nFeatEnd; i++)
aLang.rgch[i-pos] = features[i];
- std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
+ sil_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
= font.getSupportedLanguages();
gr::LanguageIterator iL = aSupported.first;
while (iL != aSupported.second)
@@ -142,7 +142,7 @@ void GrFeatureParser::setLang(gr::Font & font, const std::string & lang)
if (lang[i] == '-') break;
aLang.rgch[i] = lang[i];
}
- std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
+ sil_std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported
= font.getSupportedLanguages();
gr::LanguageIterator iL = aSupported.first;
while (iL != aSupported.second)
@@ -189,7 +189,7 @@ bool GrFeatureParser::isValid(gr::Font & font, gr::FeatureSetting & setting)
{
return false;
}
- std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator >
+ sil_std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator >
validValues = font.getFeatureSettings(i);
gr::FeatureSettingIterator j = validValues.first;
while (j != validValues.second)
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 86dee2749efa..6f4e13c7985f 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -66,11 +66,13 @@
#include <unicode/uscript.h>
// Graphite Libraries (must be after vcl headers on windows)
+#include "pregraphitestl.h"
#include <graphite/GrClient.h>
#include <graphite/Font.h>
#include <graphite/ITextSource.h>
#include <graphite/Segment.h>
#include <graphite/SegmentPainter.h>
+#include "postgraphitestl.h"
#include <vcl/graphite_layout.hxx>
#include <vcl/graphite_features.hxx>
@@ -105,8 +107,8 @@ FILE * grLog()
namespace
{
- typedef std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t;
- typedef std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t;
+ typedef sil_std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t;
+ typedef sil_std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t;
inline long round(const float n) {
return long(n + (n < 0 ? -0.5 : 0.5));
@@ -171,7 +173,7 @@ GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs,
bool bRtl, long &rWidth, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs)
{
// Create a glyph item for each of the glyph and append it to the base class glyph list.
- typedef std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet;
+ typedef sil_std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet;
int nChar = rArgs.mnEndCharPos - rArgs.mnMinCharPos;
glyph_range_t iGlyphs = rSegment.glyphs();
int nGlyphs = iGlyphs.second - iGlyphs.first;
@@ -586,7 +588,7 @@ public:
sal_Int32 hashCode(const grutils::GrFeatureParser * mpFeatures)
{
// is this sufficient?
- std::wstring aFace;
+ sil_std::wstring aFace;
bool bBold;
bool bItalic;
UniqueCacheInfo(aFace, bBold, bItalic);
@@ -720,6 +722,7 @@ bool GraphiteLayout::LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment)
#ifdef GRCACHE_REUSE_VECTORS
// if we have an exact match, then we can reuse the glyph vectors from before
if (pSegRecord && (pSegRecord->glyphs().size() > 0) &&
+ (pSegRecord->fontScale() == mfScaling) &&
!(SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags) )
{
mnWidth = pSegRecord->width();
@@ -765,7 +768,8 @@ bool GraphiteLayout::LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment)
!(SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags))
{
pSegRecord->setGlyphVectors(mnWidth, mvGlyphs, mvCharDxs,
- mvChar2BaseGlyph, mvGlyph2Char);
+ mvChar2BaseGlyph, mvGlyph2Char,
+ mfScaling);
}
#endif
#endif
diff --git a/vcl/source/glyphs/graphite_textsrc.cxx b/vcl/source/glyphs/graphite_textsrc.cxx
index adc2ae99c4f8..cbbd386e734a 100644
--- a/vcl/source/glyphs/graphite_textsrc.cxx
+++ b/vcl/source/glyphs/graphite_textsrc.cxx
@@ -138,16 +138,16 @@ gr::isocode TextSourceAdaptor::getLanguage(gr::toffset)
return unknown;
}
-std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx)
+sil_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx)
{
if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos))
- return std::make_pair(0, maLayoutArgs.mnMinCharPos);
+ return sil_std::make_pair(0, maLayoutArgs.mnMinCharPos);
if (nCharIdx < mnEnd)
- return std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd);
+ return sil_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd);
- return std::make_pair(mnEnd, maLayoutArgs.mnLength);
+ return sil_std::make_pair(mnEnd, maLayoutArgs.mnLength);
}
size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings)
@@ -159,7 +159,7 @@ size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * sett
bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2)
{
- const std::pair<gr::toffset, gr::toffset>
+ const sil_std::pair<gr::toffset, gr::toffset>
range1 = propertyRange(char_idx1),
range2 = propertyRange(char_idx2);
diff --git a/vcl/source/glyphs/graphite_textsrc.hxx b/vcl/source/glyphs/graphite_textsrc.hxx
index 6f701988bb01..62d951c3f950 100644
--- a/vcl/source/glyphs/graphite_textsrc.hxx
+++ b/vcl/source/glyphs/graphite_textsrc.hxx
@@ -62,9 +62,11 @@
#include "vcl/dllapi.h"
// Libraries
+#include "pregraphitestl.h"
#include <graphite/GrClient.h>
#include <graphite/Font.h>
#include <graphite/ITextSource.h>
+#include "postgraphitestl.h"
// Module type definitions and forward declarations.
//
@@ -91,7 +93,7 @@ public:
virtual float getVerticalOffset(gr::toffset ich);
virtual gr::isocode getLanguage(gr::toffset ich);
- virtual std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich);
+ virtual sil_std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich);
virtual size_t getFontFeatures(gr::toffset ich, gr::FeatureSetting * prgfset);
virtual bool sameSegment(gr::toffset ich1, gr::toffset ich2);
diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx
index c6f64d74c5fc..a332c89dc9be 100644
--- a/vcl/source/window/dlgctrl.cxx
+++ b/vcl/source/window/dlgctrl.cxx
@@ -36,6 +36,7 @@
#include <vcl/svapp.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/tabctrl.hxx>
+#include <vcl/tabdlg.hxx>
#include <vcl/button.hxx>
#include <vcl/window.h>
@@ -888,6 +889,20 @@ BOOL Window::ImplDlgCtrl( const KeyEvent& rKEvt, BOOL bKeyInput )
return TRUE;
}
+ // if we have come here (and therefore the strange "formular" logic above
+ // turned up no result, then let's try to find a customer for Ctrl-TAB
+ if ( nKeyCode == KEY_TAB && aKeyCode.IsMod1() && ! aKeyCode.IsMod2() )
+ {
+ TabDialog* pDlg = dynamic_cast<TabDialog*>(this);
+ if( pDlg )
+ {
+ TabControl* pTabCtrl = pDlg->ImplGetFirstTabControl();
+ NotifyEvent aEvt( bKeyInput ? EVENT_KEYINPUT : EVENT_KEYUP,
+ pTabCtrl, &rKEvt );
+ return pTabCtrl->ImplHandleNotifyEvent( aEvt );
+ }
+ }
+
return FALSE;
}
diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk
index 21b8efe4c586..8b3c01f5721e 100644
--- a/vcl/source/window/makefile.mk
+++ b/vcl/source/window/makefile.mk
@@ -70,6 +70,7 @@ SLOFILES= \
$(SLO)$/mnemonic.obj \
$(SLO)$/mnemonicengine.obj \
$(SLO)$/msgbox.obj \
+ $(SLO)$/popupmenuwindow.obj \
$(SLO)$/scrwnd.obj \
$(SLO)$/printdlg.obj \
$(SLO)$/seleng.obj \
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index c9e0c23e7f16..5b99cd084360 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -5578,6 +5578,17 @@ BOOL MenuBarWindow::ImplHandleKeyEvent( const KeyEvent& rKEvent, BOOL bFromMenu
n = pMenu->GetItemCount()-1;
}
+ // handling gtk like (aka mbOpenMenuOnF10)
+ // do not highlight an item when opening a sub menu
+ // unless there already was a higlighted sub menu item
+ bool bWasHighlight = false;
+ if( pActivePopup )
+ {
+ MenuFloatingWindow* pSubWindow = dynamic_cast<MenuFloatingWindow*>(pActivePopup->ImplGetWindow());
+ if( pSubWindow )
+ bWasHighlight = (pSubWindow->GetHighlightedItem() != ITEMPOS_INVALID);
+ }
+
USHORT nLoop = n;
if( nCode == KEY_HOME )
@@ -5604,7 +5615,10 @@ BOOL MenuBarWindow::ImplHandleKeyEvent( const KeyEvent& rKEvent, BOOL bFromMenu
MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
if ( ( pData->eType != MENUITEM_SEPARATOR ) && pMenu->ImplIsVisible( n ) )
{
- ChangeHighlightItem( n, TRUE );
+ BOOL bDoSelect = TRUE;
+ if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 )
+ bDoSelect = bWasHighlight;
+ ChangeHighlightItem( n, bDoSelect );
break;
}
} while ( n != nLoop );
diff --git a/vcl/source/window/popupmenuwindow.cxx b/vcl/source/window/popupmenuwindow.cxx
new file mode 100644
index 000000000000..29d60a7cc02d
--- /dev/null
+++ b/vcl/source/window/popupmenuwindow.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: floatwin.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * 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/popupmenuwindow.hxx"
+
+#include <limits>
+
+struct PopupMenuFloatingWindow::ImplData
+{
+ sal_uInt16 mnMenuStackLevel; // Store the stack level of a popup menu. 0 = top-level menu.
+
+ ImplData();
+ ~ImplData();
+};
+
+PopupMenuFloatingWindow::ImplData::ImplData() :
+ mnMenuStackLevel( ::std::numeric_limits<sal_uInt16>::max() )
+{
+}
+
+PopupMenuFloatingWindow::ImplData::~ImplData()
+{
+}
+
+// ============================================================================
+
+PopupMenuFloatingWindow::PopupMenuFloatingWindow( Window* pParent, WinBits nStyle ) :
+ FloatingWindow(pParent, nStyle),
+ mpImplData(new ImplData)
+{
+}
+
+PopupMenuFloatingWindow::~PopupMenuFloatingWindow()
+{
+ delete mpImplData;
+}
+
+sal_uInt16 PopupMenuFloatingWindow::GetMenuStackLevel() const
+{
+ return mpImplData->mnMenuStackLevel;
+}
+
+void PopupMenuFloatingWindow::SetMenuStackLevel( sal_uInt16 nLevel )
+{
+ mpImplData->mnMenuStackLevel = nLevel;
+}
+
+bool PopupMenuFloatingWindow::IsPopupMenu() const
+{
+ return mpImplData->mnMenuStackLevel != ::std::numeric_limits<sal_uInt16>::max();
+}
+
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
index ede3bcc107aa..8d986f691963 100644
--- a/vcl/source/window/status.cxx
+++ b/vcl/source/window/status.cxx
@@ -156,6 +156,7 @@ void StatusBar::ImplInit( Window* pParent, WinBits nStyle )
mbProgressMode = FALSE;
mbInUserDraw = FALSE;
mbBottomBorder = FALSE;
+ mnItemsWidth = STATUSBAR_OFFSET_X;
mnDX = 0;
mnDY = 0;
mnCalcHeight = 0;
diff --git a/vcl/source/window/tabdlg.cxx b/vcl/source/window/tabdlg.cxx
index 95fb404d24af..217533c8d6b7 100644
--- a/vcl/source/window/tabdlg.cxx
+++ b/vcl/source/window/tabdlg.cxx
@@ -276,3 +276,21 @@ void TabDialog::AdjustLayout()
{
ImplPosControls();
}
+
+// -----------------------------------------------------------------------
+
+TabControl* TabDialog::ImplGetFirstTabControl() const
+{
+ Window* pChild = GetWindow( WINDOW_FIRSTCHILD );
+ while ( pChild )
+ {
+ if ( pChild->IsVisible() && (pChild != mpViewWindow) )
+ {
+ if ( pChild->GetType() == WINDOW_TABCONTROL )
+ return (TabControl*)pChild;
+ }
+ pChild = pChild->GetWindow( WINDOW_NEXT );
+ }
+ return NULL;
+}
+
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index ca0ebb10a4e9..5689972e69d6 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -699,6 +699,7 @@ void Window::ImplInitWindowData( WindowType nType )
mpWindowImpl->mbDisableAccessibleLabelForRelation = FALSE; // TRUE: do not set LabelFor relation on accessible objects
mpWindowImpl->mbDisableAccessibleLabeledByRelation = FALSE; // TRUE: do not set LabeledBy relation on accessible objects
mpWindowImpl->mbHelpTextDynamic = FALSE; // TRUE: append help id in HELP_DEBUG case
+ mpWindowImpl->mbFakeFocusSet = FALSE; // TRUE: pretend as if the window has focus.
mbEnableRTL = Application::GetSettings().GetLayoutRTL(); // TRUE: this outdev will be mirrored if RTL window layout (UI mirroring) is globally active
}
@@ -3915,6 +3916,20 @@ void Window::ImplCallFocusChangeActivate( Window* pNewOverlapWindow,
}
}
+static bool IsWindowFocused(const WindowImpl& rWinImpl)
+{
+ if (rWinImpl.mpSysObj)
+ return true;
+
+ if (rWinImpl.mpFrameData->mbHasFocus)
+ return true;
+
+ if (rWinImpl.mbFakeFocusSet)
+ return true;
+
+ return false;
+}
+
// -----------------------------------------------------------------------
void Window::ImplGrabFocus( USHORT nFlags )
{
@@ -3986,9 +4001,7 @@ void Window::ImplGrabFocus( USHORT nFlags )
pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
}
- BOOL bHasFocus = TRUE;
- if ( !mpWindowImpl->mpSysObj && !mpWindowImpl->mpFrameData->mbHasFocus )
- bHasFocus = FALSE;
+ bool bHasFocus = IsWindowFocused(*mpWindowImpl);
BOOL bMustNotGrabFocus = FALSE;
// #100242#, check parent hierarchy if some floater prohibits grab focus
@@ -4759,7 +4772,10 @@ void Window::doLazyDelete()
SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
+ {
+ Show( FALSE );
SetParent( ImplGetDefaultWindow() );
+ }
vcl::LazyDeletor<Window>::Delete( this );
}
@@ -5381,6 +5397,11 @@ void Window::CallEventListeners( ULONG nEvent, void* pData )
}
}
+void Window::FireVclEvent( VclSimpleEvent* pEvent )
+{
+ ImplGetSVData()->mpApp->ImplCallEventListeners(pEvent);
+}
+
// -----------------------------------------------------------------------
void Window::AddEventListener( const Link& rEventListener )
@@ -7756,6 +7777,11 @@ void Window::GrabFocusToDocument()
}
}
+void Window::SetFakeFocus( bool bFocus )
+{
+ ImplGetWindowImpl()->mbFakeFocusSet = bFocus;
+}
+
// -----------------------------------------------------------------------
BOOL Window::HasChildPathFocus( BOOL bSystemWindow ) const
diff --git a/vcl/unx/gtk/a11y/atkutil.cxx b/vcl/unx/gtk/a11y/atkutil.cxx
index c92a69d3fb49..f5db066151d3 100644
--- a/vcl/unx/gtk/a11y/atkutil.cxx
+++ b/vcl/unx/gtk/a11y/atkutil.cxx
@@ -666,7 +666,16 @@ long WindowEventHandler(void *, ::VclSimpleEvent const * pEvent)
static_cast< ::VclWindowEvent const * >(pEvent)->GetWindow());
*/
case VCLEVENT_MENU_HIGHLIGHT:
- handle_menu_highlighted(static_cast< ::VclMenuEvent const * >(pEvent));
+ if (const VclMenuEvent* pMenuEvent = dynamic_cast<const VclMenuEvent*>(pEvent))
+ {
+ handle_menu_highlighted(pMenuEvent);
+ }
+ else if (const VclAccessibleEvent* pAccEvent = dynamic_cast<const VclAccessibleEvent*>(pEvent))
+ {
+ uno::Reference< accessibility::XAccessible > xAccessible = pAccEvent->GetAccessible();
+ if (xAccessible.is())
+ atk_wrapper_focus_tracker_notify_when_idle(xAccessible);
+ }
break;
case VCLEVENT_TOOLBOX_HIGHLIGHT:
diff --git a/vcl/unx/gtk/a11y/atkwindow.cxx b/vcl/unx/gtk/a11y/atkwindow.cxx
index 5961556e85d7..1bda4eea774e 100644
--- a/vcl/unx/gtk/a11y/atkwindow.cxx
+++ b/vcl/unx/gtk/a11y/atkwindow.cxx
@@ -33,6 +33,7 @@
#include <plugins/gtk/gtkframe.hxx>
#include <vcl/window.hxx>
+#include "vcl/popupmenuwindow.hxx"
#include "atkwindow.hxx"
#include "atkwrapper.hxx"
@@ -108,6 +109,17 @@ init_from_window( AtkObject *accessible, Window *pWindow )
pChild->SetAccessibleRole( AccessibleRole::LABEL );
accessible->name = g_strdup( rtl::OUStringToOString( pChild->GetText(), RTL_TEXTENCODING_UTF8 ).getStr() );
}
+ else if ( pWindow->GetType() == WINDOW_BORDERWINDOW && pChild->GetType() == WINDOW_FLOATINGWINDOW )
+ {
+ PopupMenuFloatingWindow* p = dynamic_cast<PopupMenuFloatingWindow*>(pChild);
+ if (p && p->IsPopupMenu() && p->GetMenuStackLevel() == 0)
+ {
+ // This is a top-level menu popup. Register it.
+ role = ATK_ROLE_POPUP_MENU;
+ pChild->SetAccessibleRole( AccessibleRole::POPUP_MENU );
+ accessible->name = g_strdup( rtl::OUStringToOString( pChild->GetText(), RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
}
break;
}
@@ -136,6 +148,23 @@ ooo_window_wrapper_real_focus_gtk (GtkWidget *, GdkEventFocus *)
/*****************************************************************************/
+static bool
+isChildPopupMenu(Window* pWindow)
+{
+ Window* pChild = pWindow->GetAccessibleChildWindow(0);
+ if (!pChild)
+ return false;
+
+ if (WINDOW_FLOATINGWINDOW != pChild->GetType())
+ return false;
+
+ PopupMenuFloatingWindow* p = dynamic_cast<PopupMenuFloatingWindow*>(pChild);
+ if (!p)
+ return false;
+
+ return p->IsPopupMenu();
+}
+
static void
ooo_window_wrapper_real_initialize(AtkObject *obj, gpointer data)
{
@@ -157,8 +186,16 @@ ooo_window_wrapper_real_initialize(AtkObject *obj, gpointer data)
*/
if( WINDOW_BORDERWINDOW == pWindow->GetType() )
{
- ooo_wrapper_registry_add( xAccessible, obj );
- g_object_set_data( G_OBJECT(obj), "ooo:atk-wrapper-key", xAccessible.get() );
+ if ( isChildPopupMenu(pWindow) )
+ {
+ AtkObject *child = atk_object_wrapper_new( xAccessible, obj );
+ ooo_wrapper_registry_add( xAccessible, child );
+ }
+ else
+ {
+ ooo_wrapper_registry_add( xAccessible, obj );
+ g_object_set_data( G_OBJECT(obj), "ooo:atk-wrapper-key", xAccessible.get() );
+ }
}
else
{
diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx
index 8854083e1509..302c096e5915 100644
--- a/vcl/unx/gtk/a11y/atkwrapper.cxx
+++ b/vcl/unx/gtk/a11y/atkwrapper.cxx
@@ -515,6 +515,60 @@ wrapper_ref_relation_set( AtkObject *atk_obj )
/*****************************************************************************/
+#if 0
+struct {
+ sal_Int16 value;
+ const sal_Char* name;
+} aStateTypeTable[] = {
+ { accessibility::AccessibleStateType::INVALID, "INVALID" },
+ { accessibility::AccessibleStateType::ACTIVE, "ACTIVE" },
+ { accessibility::AccessibleStateType::ARMED, "ARMED" },
+ { accessibility::AccessibleStateType::BUSY, "BUSY" },
+ { accessibility::AccessibleStateType::CHECKED, "CHECKED" },
+ { accessibility::AccessibleStateType::DEFUNC, "DEFUNC" },
+ { accessibility::AccessibleStateType::EDITABLE, "EDITABLE" },
+ { accessibility::AccessibleStateType::ENABLED, "ENABLED" },
+ { accessibility::AccessibleStateType::EXPANDABLE, "EXPANDABLE" },
+ { accessibility::AccessibleStateType::EXPANDED, "EXPANDED" },
+ { accessibility::AccessibleStateType::FOCUSABLE, "FOCUSABLE" },
+ { accessibility::AccessibleStateType::FOCUSED, "FOCUSED" },
+ { accessibility::AccessibleStateType::HORIZONTAL, "HORIZONTAL" },
+ { accessibility::AccessibleStateType::ICONIFIED, "ICONIFIED" },
+ { accessibility::AccessibleStateType::INDETERMINATE, "INDETERMINATE" },
+ { accessibility::AccessibleStateType::MANAGES_DESCENDANTS, "MANAGES_DESCENDANTS" },
+ { accessibility::AccessibleStateType::MODAL, "MODAL" },
+ { accessibility::AccessibleStateType::MULTI_LINE, "MULTI_LINE" },
+ { accessibility::AccessibleStateType::MULTI_SELECTABLE, "MULTI_SELECTABLE" },
+ { accessibility::AccessibleStateType::OPAQUE, "OPAQUE" },
+ { accessibility::AccessibleStateType::PRESSED, "PRESSED" },
+ { accessibility::AccessibleStateType::RESIZABLE, "RESIZABLE" },
+ { accessibility::AccessibleStateType::SELECTABLE, "SELECTABLE" },
+ { accessibility::AccessibleStateType::SELECTED, "SELECTED" },
+ { accessibility::AccessibleStateType::SENSITIVE, "SENSITIVE" },
+ { accessibility::AccessibleStateType::SHOWING, "SHOWING" },
+ { accessibility::AccessibleStateType::SINGLE_LINE, "SINGLE_LINE" },
+ { accessibility::AccessibleStateType::STALE, "STALE" },
+ { accessibility::AccessibleStateType::TRANSIENT, "TRANSIENT" },
+ { accessibility::AccessibleStateType::VERTICAL, "VERTICAL" },
+ { accessibility::AccessibleStateType::VISIBLE, "VISIBLE" }
+};
+
+static void printStates(const uno::Sequence<sal_Int16>& rStates)
+{
+ sal_Int32 n = rStates.getLength();
+ size_t nTypes = sizeof(aStateTypeTable)/sizeof(aStateTypeTable[0]);
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ for (size_t j = 0; j < nTypes; ++j)
+ {
+ if (aStateTypeTable[j].value == rStates[i])
+ printf("%s ", aStateTypeTable[j].name);
+ }
+ }
+ printf("\n");
+}
+#endif
+
static AtkStateSet *
wrapper_ref_state_set( AtkObject *atk_obj )
{
diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx
index af3a1df97a8c..92a8ff641a38 100644
--- a/vcl/unx/gtk/app/gtkinst.cxx
+++ b/vcl/unx/gtk/app/gtkinst.cxx
@@ -144,11 +144,6 @@ extern "C"
if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
XInitThreads();
- #if OSL_DEBUG_LEVEL > 1
- int nFd = open( "/home/pl93762/log.txt", O_CREAT | O_TRUNC | O_WRONLY, 0755 );
- dup2( nFd, STDERR_FILENO );
- #endif
-
const gchar* pVersion = gtk_check_version( 2, 2, 0 );
if( pVersion )
{
diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx
index 92ff2d3b8d8e..69f42637d203 100644
--- a/vcl/unx/gtk/window/gtkframe.cxx
+++ b/vcl/unx/gtk/window/gtkframe.cxx
@@ -1315,7 +1315,7 @@ void GtkSalFrame::Show( BOOL bVisible, BOOL bNoActivate )
setMinMaxSize();
// #i45160# switch to desktop where a dialog with parent will appear
- if( m_pParent && m_pParent->m_nWorkArea != m_nWorkArea )
+ if( m_pParent && m_pParent->m_nWorkArea != m_nWorkArea && GTK_WIDGET_MAPPED(m_pParent->m_pWindow) )
getDisplay()->getWMAdaptor()->switchToWorkArea( m_pParent->m_nWorkArea );
if( isFloatGrabWindow() &&
diff --git a/vcl/unx/headless/svpprn.cxx b/vcl/unx/headless/svpprn.cxx
index 75d86959b2b5..2c0ba3dad84c 100644
--- a/vcl/unx/headless/svpprn.cxx
+++ b/vcl/unx/headless/svpprn.cxx
@@ -736,7 +736,7 @@ String PspSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, ULONG
{
const PPDValue* pValue = pKey->getValue( nPaperBin );
if( pValue )
- aRet = pValue->m_aOptionTranslation.Len() ? pValue->m_aOptionTranslation : pValue->m_aOption;
+ aRet = aData.m_pParser->translateOption( pKey->getKey(), pValue->m_aOption );
}
}
diff --git a/vcl/unx/source/app/randrwrapper.cxx b/vcl/unx/source/app/randrwrapper.cxx
index 4fbe5db97ab9..85f60a07903a 100644
--- a/vcl/unx/source/app/randrwrapper.cxx
+++ b/vcl/unx/source/app/randrwrapper.cxx
@@ -288,6 +288,9 @@ void RandRWrapper::releaseWrapper()
#include "saldisp.hxx"
#include "salframe.h"
+#if OSL_DEBUG_LEVEL > 1
+#include <cstdio>
+#endif
void SalDisplay::InitRandR( XLIB_Window aRoot ) const
{
diff --git a/vcl/unx/source/dtrans/X11_dndcontext.cxx b/vcl/unx/source/dtrans/X11_dndcontext.cxx
index 59832c27c2a7..71aebde5b7af 100644
--- a/vcl/unx/source/dtrans/X11_dndcontext.cxx
+++ b/vcl/unx/source/dtrans/X11_dndcontext.cxx
@@ -42,8 +42,8 @@ using namespace x11;
*/
DropTargetDropContext::DropTargetDropContext(
- Window aDropWindow,
- Time aTimestamp,
+ XLIB_Window aDropWindow,
+ XLIB_Time aTimestamp,
SelectionManager& rManager ) :
m_aDropWindow( aDropWindow ),
m_nTimestamp( aTimestamp ),
@@ -77,8 +77,8 @@ void DropTargetDropContext::dropComplete( sal_Bool success ) throw()
*/
DropTargetDragContext::DropTargetDragContext(
- Window aDropWindow,
- Time aTimestamp,
+ XLIB_Window aDropWindow,
+ XLIB_Time aTimestamp,
SelectionManager& rManager ) :
m_aDropWindow( aDropWindow ),
m_nTimestamp( aTimestamp ),
@@ -106,8 +106,8 @@ void DropTargetDragContext::rejectDrag() throw()
*/
DragSourceContext::DragSourceContext(
- Window aDropWindow,
- Time aTimestamp,
+ XLIB_Window aDropWindow,
+ XLIB_Time aTimestamp,
SelectionManager& rManager ) :
m_aDropWindow( aDropWindow ),
m_nTimestamp( aTimestamp ),
diff --git a/vcl/unx/source/dtrans/X11_dndcontext.hxx b/vcl/unx/source/dtrans/X11_dndcontext.hxx
index f2ecb7b0841b..3626b86d8617 100644
--- a/vcl/unx/source/dtrans/X11_dndcontext.hxx
+++ b/vcl/unx/source/dtrans/X11_dndcontext.hxx
@@ -36,7 +36,9 @@
#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp>
#include <cppuhelper/implbase1.hxx>
+#include "tools/prex.h"
#include <X11/Xlib.h>
+#include "tools/postx.h"
using namespace com::sun::star::uno;
@@ -49,12 +51,12 @@ namespace x11 {
::com::sun::star::datatransfer::dnd::XDropTargetDropContext
>
{
- Window m_aDropWindow;
- Time m_nTimestamp;
+ XLIB_Window m_aDropWindow;
+ XLIB_Time m_nTimestamp;
SelectionManager& m_rManager;
Reference< XInterface > m_xManagerRef;
public:
- DropTargetDropContext( Window, Time, SelectionManager& );
+ DropTargetDropContext( XLIB_Window, XLIB_Time, SelectionManager& );
virtual ~DropTargetDropContext();
// XDropTargetDropContext
@@ -68,12 +70,12 @@ namespace x11 {
::com::sun::star::datatransfer::dnd::XDropTargetDragContext
>
{
- Window m_aDropWindow;
- Time m_nTimestamp;
+ XLIB_Window m_aDropWindow;
+ XLIB_Time m_nTimestamp;
SelectionManager& m_rManager;
Reference< XInterface > m_xManagerRef;
public:
- DropTargetDragContext( Window, Time, SelectionManager& );
+ DropTargetDragContext( XLIB_Window, XLIB_Time, SelectionManager& );
virtual ~DropTargetDragContext();
// XDropTargetDragContext
@@ -86,12 +88,12 @@ namespace x11 {
::com::sun::star::datatransfer::dnd::XDragSourceContext
>
{
- Window m_aDropWindow;
- Time m_nTimestamp;
+ XLIB_Window m_aDropWindow;
+ XLIB_Time m_nTimestamp;
SelectionManager& m_rManager;
Reference< XInterface > m_xManagerRef;
public:
- DragSourceContext( Window, Time, SelectionManager& );
+ DragSourceContext( XLIB_Window, XLIB_Time, SelectionManager& );
virtual ~DragSourceContext();
// XDragSourceContext
diff --git a/vcl/unx/source/dtrans/X11_selection.cxx b/vcl/unx/source/dtrans/X11_selection.cxx
index c6036ae4f78e..e549d92d9c5f 100644
--- a/vcl/unx/source/dtrans/X11_selection.cxx
+++ b/vcl/unx/source/dtrans/X11_selection.cxx
@@ -35,11 +35,13 @@
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
+#include "tools/prex.h"
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/X.h>
#include <X11/Xutil.h>
+#include "tools/postx.h"
#if defined(LINUX) || defined(NETBSD) || defined (FREEBSD)
#include <sys/poll.h>
#else
@@ -53,6 +55,8 @@
#include <X11_dndcontext.hxx>
#include <bmp.hxx>
+#include "vcl/svapp.hxx"
+
// pointer bitmaps
#include <copydata_curs.h>
#include <copydata_mask.h>
@@ -66,9 +70,9 @@
#include <com/sun/star/awt/MouseEvent.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <rtl/tencinfo.h>
-#ifndef OSL_PROCESS_H
#include <osl/process.h>
-#endif
+
+#include <comphelper/processfactory.hxx>
#define DRAG_EVENT_MASK ButtonPressMask |\
ButtonReleaseMask |\
@@ -81,6 +85,7 @@ using namespace com::sun::star::datatransfer::dnd;
using namespace com::sun::star::lang;
using namespace com::sun::star::awt;
using namespace com::sun::star::uno;
+using namespace com::sun::star::frame;
using namespace cppu;
using namespace osl;
using namespace rtl;
@@ -280,7 +285,7 @@ SelectionManager::SelectionManager() :
m_aDragRunning.reset();
}
-Cursor SelectionManager::createCursor( const char* pPointerData, const char* pMaskData, int width, int height, int hotX, int hotY )
+XLIB_Cursor SelectionManager::createCursor( const char* pPointerData, const char* pMaskData, int width, int height, int hotX, int hotY )
{
Pixmap aPointer;
Pixmap aMask;
@@ -306,7 +311,7 @@ Cursor SelectionManager::createCursor( const char* pPointerData, const char* pMa
pMaskData,
width,
height );
- Cursor aCursor =
+ XLIB_Cursor aCursor =
XCreatePixmapCursor( m_pDisplay, aPointer, aMask,
&aBlack, &aWhite,
hotX,
@@ -928,7 +933,7 @@ bool SelectionManager::getPasteData( Atom selection, Atom type, Sequence< sal_In
if( it == m_aSelections.end() )
return false;
- Window aSelectionOwner = XGetSelectionOwner( m_pDisplay, selection );
+ XLIB_Window aSelectionOwner = XGetSelectionOwner( m_pDisplay, selection );
if( aSelectionOwner == None )
return false;
if( aSelectionOwner == m_aWindow )
@@ -1480,7 +1485,7 @@ static sal_Size GetTrueFormatSize(int nFormat)
}
bool SelectionManager::sendData( SelectionAdaptor* pAdaptor,
- Window requestor,
+ XLIB_Window requestor,
Atom target,
Atom property,
Atom selection )
@@ -1587,7 +1592,7 @@ bool SelectionManager::sendData( SelectionAdaptor* pAdaptor,
{
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "using INCR protocol\n" );
- std::hash_map< Window, std::hash_map< Atom, IncrementalTransfer > >::const_iterator win_it = m_aIncrementals.find( requestor );
+ std::hash_map< XLIB_Window, std::hash_map< Atom, IncrementalTransfer > >::const_iterator win_it = m_aIncrementals.find( requestor );
if( win_it != m_aIncrementals.end() )
{
std::hash_map< Atom, IncrementalTransfer >::const_iterator inc_it = win_it->second.find( property );
@@ -1986,7 +1991,7 @@ bool SelectionManager::handleSendPropertyNotify( XPropertyEvent& rNotify )
// feed incrementals
if( rNotify.state == PropertyDelete )
{
- std::hash_map< Window, std::hash_map< Atom, IncrementalTransfer > >::iterator it;
+ std::hash_map< XLIB_Window, std::hash_map< Atom, IncrementalTransfer > >::iterator it;
it = m_aIncrementals.find( rNotify.window );
if( it != m_aIncrementals.end() )
{
@@ -2168,12 +2173,12 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
ResettableMutexGuard aGuard(m_aMutex);
// handle drop related events
- Window aSource = rMessage.data.l[0];
- Window aTarget = rMessage.window;
+ XLIB_Window aSource = rMessage.data.l[0];
+ XLIB_Window aTarget = rMessage.window;
bool bHandled = false;
- ::std::hash_map< Window, DropTargetEntry >::iterator it =
+ ::std::hash_map< XLIB_Window, DropTargetEntry >::iterator it =
m_aDropTargets.find( aTarget );
#if OSL_DEBUG_LEVEL > 1
@@ -2187,7 +2192,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
fprintf( stderr, "but no target found\n" );
else if( ! it->second.m_pTarget->m_bActive )
fprintf( stderr, "but target is inactive\n" );
- else if( m_aDropEnterEvent.data.l[0] != None && (Window)m_aDropEnterEvent.data.l[0] != aSource )
+ else if( m_aDropEnterEvent.data.l[0] != None && (XLIB_Window)m_aDropEnterEvent.data.l[0] != aSource )
fprintf( stderr, "but source 0x%lx is unknown (expected 0x%lx or 0)\n", aSource, m_aDropEnterEvent.data.l[0] );
else
fprintf( stderr, "processing.\n" );
@@ -2208,7 +2213,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
if( it != m_aDropTargets.end() &&
it->second.m_pTarget->m_bActive &&
- ( m_aDropEnterEvent.data.l[0] == None || Window(m_aDropEnterEvent.data.l[0]) == aSource )
+ ( m_aDropEnterEvent.data.l[0] == None || XLIB_Window(m_aDropEnterEvent.data.l[0]) == aSource )
)
{
if( rMessage.message_type == m_nXdndEnter )
@@ -2224,7 +2229,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
}
else if(
rMessage.message_type == m_nXdndPosition &&
- aSource == Window(m_aDropEnterEvent.data.l[0])
+ aSource == XLIB_Window(m_aDropEnterEvent.data.l[0])
)
{
bHandled = true;
@@ -2232,7 +2237,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
if( ! m_bDropEnterSent )
m_nDropTimestamp = m_nDropTime;
- Window aChild;
+ XLIB_Window aChild;
XTranslateCoordinates( m_pDisplay,
it->second.m_aRootWindow,
it->first,
@@ -2280,7 +2285,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
}
else if(
rMessage.message_type == m_nXdndLeave &&
- aSource == Window(m_aDropEnterEvent.data.l[0])
+ aSource == XLIB_Window(m_aDropEnterEvent.data.l[0])
)
{
bHandled = true;
@@ -2298,7 +2303,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
}
else if(
rMessage.message_type == m_nXdndDrop &&
- aSource == Window(m_aDropEnterEvent.data.l[0])
+ aSource == XLIB_Window(m_aDropEnterEvent.data.l[0])
)
{
bHandled = true;
@@ -2345,7 +2350,7 @@ bool SelectionManager::handleDropEvent( XClientMessageEvent& rMessage )
* methods for XDropTargetDropContext
*/
-void SelectionManager::dropComplete( sal_Bool bSuccess, Window aDropWindow, Time )
+void SelectionManager::dropComplete( sal_Bool bSuccess, XLIB_Window aDropWindow, XLIB_Time )
{
ClearableMutexGuard aGuard(m_aMutex);
@@ -2542,21 +2547,21 @@ bool SelectionManager::updateDragAction( int modifierState )
// ------------------------------------------------------------------------
-void SelectionManager::sendDropPosition( bool bForce, Time eventTime )
+void SelectionManager::sendDropPosition( bool bForce, XLIB_Time eventTime )
{
ClearableMutexGuard aGuard(m_aMutex);
if( m_bDropSent )
return;
- ::std::hash_map< Window, DropTargetEntry >::const_iterator it =
+ ::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
m_aDropTargets.find( m_aDropWindow );
if( it != m_aDropTargets.end() )
{
if( it->second.m_pTarget->m_bActive )
{
int x, y;
- Window aChild;
+ XLIB_Window aChild;
XTranslateCoordinates( m_pDisplay, it->second.m_aRootWindow, m_aDropWindow, m_nLastDragX, m_nLastDragY, &x, &y, &aChild );
DropTargetDragEvent dtde;
dtde.Source = static_cast< OWeakObject* >(it->second.m_pTarget );
@@ -2612,7 +2617,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
bool bHandled = false;
// for shortcut
- ::std::hash_map< Window, DropTargetEntry >::const_iterator it =
+ ::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
m_aDropTargets.find( m_aDropWindow );
#if OSL_DEBUG_LEVEL > 1
switch( rMessage.type )
@@ -2635,7 +2640,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
case ButtonRelease:
fprintf( stderr, "handleDragEvent: ButtonRelease %d (m_nDragButton = %d)\n", rMessage.xbutton.button, m_nDragButton );
break;
- case KeyPress:
+ case XLIB_KeyPress:
fprintf( stderr, "handleDragEvent: KeyPress\n" );
break;
case KeyRelease:
@@ -2719,7 +2724,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
bool bForce = false;
int root_x = rMessage.type == MotionNotify ? rMessage.xmotion.x_root : rMessage.xcrossing.x_root;
int root_y = rMessage.type == MotionNotify ? rMessage.xmotion.y_root : rMessage.xcrossing.y_root;
- Window root = rMessage.type == MotionNotify ? rMessage.xmotion.root : rMessage.xcrossing.root;
+ XLIB_Window root = rMessage.type == MotionNotify ? rMessage.xmotion.root : rMessage.xcrossing.root;
m_nDragTimestamp = rMessage.type == MotionNotify ? rMessage.xmotion.time : rMessage.xcrossing.time;
aGuard.clear();
@@ -2736,7 +2741,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
sendDropPosition( bForce, rMessage.type == MotionNotify ? rMessage.xmotion.time : rMessage.xcrossing.time );
}
}
- else if( rMessage.type == KeyPress || rMessage.type == KeyRelease )
+ else if( rMessage.type == XLIB_KeyPress || rMessage.type == KeyRelease )
{
bHandled = true;
KeySym aKey = XKeycodeToKeysym( m_pDisplay, rMessage.xkey.keycode, 0 );
@@ -2793,7 +2798,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
case XK_Control_L: nNewState = ControlMask;break;
// just interested in shift and ctrl for dnd
}
- if( rMessage.type == KeyPress )
+ if( rMessage.type == XLIB_KeyPress )
nState |= nNewState;
else
nState &= ~nNewState;
@@ -2815,7 +2820,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
{
bHandled = true;
int x, y;
- Window aChild;
+ XLIB_Window aChild;
XTranslateCoordinates( m_pDisplay, rMessage.xbutton.root, m_aDropWindow, rMessage.xbutton.x_root, rMessage.xbutton.y_root, &x, &y, &aChild );
DropTargetDropEvent dtde;
dtde.Source = static_cast< OWeakObject* >(it->second.m_pTarget );
@@ -2865,7 +2870,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
{
bHandled = true;
- Window aDummy;
+ XLIB_Window aDummy;
XEvent aEvent;
aEvent.type = ButtonPress;
aEvent.xbutton.display = m_pDisplay;
@@ -2924,7 +2929,7 @@ bool SelectionManager::handleDragEvent( XEvent& rMessage )
// ------------------------------------------------------------------------
-void SelectionManager::accept( sal_Int8 dragOperation, Window aDropWindow, Time )
+void SelectionManager::accept( sal_Int8 dragOperation, XLIB_Window aDropWindow, XLIB_Time )
{
if( aDropWindow == m_aCurrentDropWindow )
{
@@ -2946,7 +2951,7 @@ void SelectionManager::accept( sal_Int8 dragOperation, Window aDropWindow, Time
// ------------------------------------------------------------------------
-void SelectionManager::reject( Window aDropWindow, Time )
+void SelectionManager::reject( XLIB_Window aDropWindow, XLIB_Time )
{
if( aDropWindow == m_aCurrentDropWindow )
{
@@ -2982,7 +2987,7 @@ sal_Bool SelectionManager::isDragImageSupported() throw()
sal_Int32 SelectionManager::getDefaultCursor( sal_Int8 dragAction ) throw()
{
- Cursor aCursor = m_aNoneCursor;
+ XLIB_Cursor aCursor = m_aNoneCursor;
if( dragAction & DNDConstants::ACTION_MOVE )
aCursor = m_aMoveCursor;
else if( dragAction & DNDConstants::ACTION_COPY )
@@ -2994,7 +2999,7 @@ sal_Int32 SelectionManager::getDefaultCursor( sal_Int8 dragAction ) throw()
// ------------------------------------------------------------------------
-int SelectionManager::getXdndVersion( Window aWindow, Window& rProxy )
+int SelectionManager::getXdndVersion( XLIB_Window aWindow, XLIB_Window& rProxy )
{
Atom* pProperties = NULL;
int nProperties = 0;
@@ -3022,7 +3027,7 @@ int SelectionManager::getXdndVersion( Window aWindow, Window& rProxy )
if( pBytes )
{
if( nType == XA_WINDOW )
- rProxy = *(Window*)pBytes;
+ rProxy = *(XLIB_Window*)pBytes;
XFree( pBytes );
pBytes = NULL;
if( rProxy != None )
@@ -3032,7 +3037,7 @@ int SelectionManager::getXdndVersion( Window aWindow, Window& rProxy )
&nType, &nFormat, &nItems, &nBytes, &pBytes );
if( pBytes )
{
- if( nType == XA_WINDOW && *(Window*)pBytes != rProxy )
+ if( nType == XA_WINDOW && *(XLIB_Window*)pBytes != rProxy )
rProxy = None;
XFree( pBytes );
pBytes = NULL;
@@ -3044,7 +3049,7 @@ int SelectionManager::getXdndVersion( Window aWindow, Window& rProxy )
break;
}
}
- Window aAwareWindow = rProxy != None ? rProxy : aWindow;
+ XLIB_Window aAwareWindow = rProxy != None ? rProxy : aWindow;
XGetWindowProperty( m_pDisplay, aAwareWindow, m_nXdndAware, 0, 1, False, XA_ATOM,
&nType, &nFormat, &nItems, &nBytes, &pBytes );
@@ -3062,7 +3067,7 @@ int SelectionManager::getXdndVersion( Window aWindow, Window& rProxy )
// ------------------------------------------------------------------------
-void SelectionManager::updateDragWindow( int nX, int nY, Window aRoot )
+void SelectionManager::updateDragWindow( int nX, int nY, XLIB_Window aRoot )
{
ResettableMutexGuard aGuard( m_aMutex );
@@ -3071,9 +3076,9 @@ void SelectionManager::updateDragWindow( int nX, int nY, Window aRoot )
m_nLastDragX = nX;
m_nLastDragY = nY;
- Window aParent = aRoot;
- Window aChild;
- Window aNewProxy = None, aNewCurrentWindow = None;
+ XLIB_Window aParent = aRoot;
+ XLIB_Window aChild;
+ XLIB_Window aNewProxy = None, aNewCurrentWindow = None;
int nNewProtocolVersion = -1;
int nWinX, nWinY;
@@ -3114,7 +3119,7 @@ void SelectionManager::updateDragWindow( int nX, int nY, Window aRoot )
dsde.DropAction = nNewProtocolVersion >= 0 ? m_nUserDragAction : DNDConstants::ACTION_COPY;
dsde.UserAction = nNewProtocolVersion >= 0 ? m_nUserDragAction : DNDConstants::ACTION_COPY;
- ::std::hash_map< Window, DropTargetEntry >::const_iterator it;
+ ::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it;
if( aNewCurrentWindow != m_aDropWindow )
{
#if OSL_DEBUG_LEVEL > 1
@@ -3263,11 +3268,11 @@ void SelectionManager::startDrag(
// the pointer is located in. since said window should be one
// of our DropTargets at the time of executeDrag we can use
// them for a start
- Window aRoot, aParent, aChild;
+ XLIB_Window aRoot, aParent, aChild;
int root_x, root_y, win_x, win_y;
unsigned int mask;
- ::std::hash_map< Window, DropTargetEntry >::const_iterator it;
+ ::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it;
it = m_aDropTargets.begin();
while( it != m_aDropTargets.end() )
{
@@ -3379,10 +3384,9 @@ void SelectionManager::startDrag(
m_bDropSuccess = false;
m_bWaitingForPrimaryConversion = false;
m_nDragButton = Button1; // default to left button
- if( trigger.Event.getValueTypeName().equalsAsciiL( "com.sun.star.awt.MouseEvent", 27 ) )
+ com::sun::star::awt::MouseEvent aEvent;
+ if( trigger.Event >>= aEvent )
{
- MouseEvent aEvent;
- trigger.Event >>= aEvent;
if( aEvent.Buttons & MouseButton::LEFT )
m_nDragButton = Button1;
else if( aEvent.Buttons & MouseButton::RIGHT )
@@ -3519,10 +3523,10 @@ sal_Int32 SelectionManager::getCurrentCursor()
// ------------------------------------------------------------------------
-void SelectionManager::setCursor( sal_Int32 cursor, Window aDropWindow, Time )
+void SelectionManager::setCursor( sal_Int32 cursor, XLIB_Window aDropWindow, XLIB_Time )
{
MutexGuard aGuard( m_aMutex );
- if( aDropWindow == m_aDropWindow && Cursor(cursor) != m_aCurrentCursor )
+ if( aDropWindow == m_aDropWindow && XLIB_Cursor(cursor) != m_aCurrentCursor )
{
if( m_xDragSourceListener.is() && ! m_bDropSent )
{
@@ -3535,7 +3539,7 @@ void SelectionManager::setCursor( sal_Int32 cursor, Window aDropWindow, Time )
// ------------------------------------------------------------------------
-void SelectionManager::setImage( sal_Int32, Window, Time )
+void SelectionManager::setImage( sal_Int32, XLIB_Window, XLIB_Time )
{
}
@@ -3668,7 +3672,7 @@ bool SelectionManager::handleXEvent( XEvent& rEvent )
case MotionNotify:
case ButtonPress:
case ButtonRelease:
- case KeyPress:
+ case XLIB_KeyPress:
case KeyRelease:
bHandled = handleDragEvent( rEvent );
break;
@@ -3734,6 +3738,14 @@ void SelectionManager::run( void* pThis )
timeval aLast;
gettimeofday( &aLast, 0 );
+ Reference< XMultiServiceFactory > xFact( ::comphelper::getProcessServiceFactory() );
+ if( xFact.is() )
+ {
+ Reference< XDesktop > xDesktop( xFact->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.Desktop" ) ), UNO_QUERY );
+ if( xDesktop.is() )
+ xDesktop->addTerminateListener(This);
+ }
+
while( osl_scheduleThread(This->m_aThread) )
{
This->dispatchEvent( 1000 );
@@ -3750,7 +3762,7 @@ void SelectionManager::run( void* pThis )
{
if( it->first != This->m_nXdndSelection && ! it->second->m_bOwner )
{
- Window aOwner = XGetSelectionOwner( This->m_pDisplay, it->first );
+ XLIB_Window aOwner = XGetSelectionOwner( This->m_pDisplay, it->first );
if( aOwner != it->second->m_aLastOwner )
{
it->second->m_aLastOwner = aOwner;
@@ -3774,6 +3786,40 @@ void SelectionManager::run( void* pThis )
#endif
}
+void SelectionManager::shutdown() throw()
+{
+ ResettableMutexGuard aGuard(m_aMutex);
+ // stop dispatching
+ if( m_aThread )
+ {
+ osl_terminateThread( m_aThread );
+ /*
+ * Allow thread to finish before app exits to avoid pulling the carpet
+ * out from under it if pasting is occuring during shutdown
+ *
+ * a) allow it to have the Mutex and
+ * b) reschedule to allow it to complete callbacks to any
+ * Application::GetSolarMutex protected regions, etc. e.g.
+ * TransferableHelper::getTransferDataFlavors (via
+ * SelectionManager::handleSelectionRequest) which it might
+ * currently be trying to enter.
+ *
+ * Otherwise the thread may be left still waiting on a GlobalMutex
+ * when that gets destroyed, letting the thread blow up and die
+ * when enters the section in a now dead OOo instance.
+ */
+ aGuard.clear();
+ while (osl_isThreadRunning(m_aThread))
+ Application::Reschedule();
+ osl_joinWithThread( m_aThread );
+ osl_destroyThread( m_aThread );
+ m_aThread = NULL;
+ aGuard.reset();
+ }
+ m_xDisplayConnection->removeEventHandler( Any(), this );
+ m_xDisplayConnection.clear();
+}
+
// ------------------------------------------------------------------------
sal_Bool SelectionManager::handleEvent( const Any& event ) throw()
@@ -3782,10 +3828,10 @@ sal_Bool SelectionManager::handleEvent( const Any& event ) throw()
if( (event >>= aSeq) )
{
XEvent* pEvent = (XEvent*)aSeq.getArray();
- Time nTimestamp = CurrentTime;
+ XLIB_Time nTimestamp = CurrentTime;
if( pEvent->type == ButtonPress || pEvent->type == ButtonRelease )
nTimestamp = pEvent->xbutton.time;
- else if( pEvent->type == KeyPress || pEvent->type == KeyRelease )
+ else if( pEvent->type == XLIB_KeyPress || pEvent->type == KeyRelease )
nTimestamp = pEvent->xkey.time;
else if( pEvent->type == MotionNotify )
nTimestamp = pEvent->xmotion.time;
@@ -3806,16 +3852,38 @@ sal_Bool SelectionManager::handleEvent( const Any& event ) throw()
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "SelectionManager got downing event\n" );
#endif
- MutexGuard aGuard(m_aMutex);
- // stop dispatching
- if( m_aThread )
- osl_terminateThread( m_aThread );
- m_xDisplayConnection->removeEventHandler( Any(), this );
- m_xDisplayConnection.clear();
+ shutdown();
}
return sal_True;
}
+void SAL_CALL SelectionManager::disposing( const ::com::sun::star::lang::EventObject& )
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+}
+
+void SAL_CALL SelectionManager::queryTermination( const ::com::sun::star::lang::EventObject& )
+ throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException )
+{
+}
+
+/*
+ * To be safe, shutdown needs to be called before the ~SfxApplication is called, waiting until
+ * the downing event can be too late if paste are requested during shutdown and ~SfxApplication
+ * has been called before vcl is shutdown
+ */
+void SAL_CALL SelectionManager::notifyTermination( const ::com::sun::star::lang::EventObject& rEvent )
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ Reference< XDesktop > xDesktop( rEvent.Source, UNO_QUERY );
+ if( xDesktop.is() == sal_True )
+ xDesktop->removeTerminateListener( this );
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "SelectionManager got app termination event\n" );
+ #endif
+ shutdown();
+}
+
// ------------------------------------------------------------------------
void SelectionManager::registerHandler( Atom selection, SelectionAdaptor& rAdaptor )
@@ -3846,12 +3914,12 @@ void SelectionManager::deregisterHandler( Atom selection )
// ------------------------------------------------------------------------
-void SelectionManager::registerDropTarget( Window aWindow, DropTarget* pTarget )
+void SelectionManager::registerDropTarget( XLIB_Window aWindow, DropTarget* pTarget )
{
MutexGuard aGuard(m_aMutex);
// sanity check
- ::std::hash_map< Window, DropTargetEntry >::const_iterator it =
+ ::std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
m_aDropTargets.find( aWindow );
if( it != m_aDropTargets.end() )
OSL_ASSERT( "attempt to register window as drop target twice" );
@@ -3877,7 +3945,7 @@ void SelectionManager::registerDropTarget( Window aWindow, DropTarget* pTarget )
// ------------------------------------------------------------------------
-void SelectionManager::deregisterDropTarget( Window aWindow )
+void SelectionManager::deregisterDropTarget( XLIB_Window aWindow )
{
ClearableMutexGuard aGuard(m_aMutex);
@@ -3885,7 +3953,7 @@ void SelectionManager::deregisterDropTarget( Window aWindow )
if( aWindow == m_aDragSourceWindow && m_aDragRunning.check() )
{
// abort drag
- std::hash_map< Window, DropTargetEntry >::const_iterator it =
+ std::hash_map< XLIB_Window, DropTargetEntry >::const_iterator it =
m_aDropTargets.find( m_aDropWindow );
if( it != m_aDropTargets.end() )
{
diff --git a/vcl/unx/source/dtrans/X11_selection.hxx b/vcl/unx/source/dtrans/X11_selection.hxx
index dc6c41247bbd..fa6c310ef8c1 100644
--- a/vcl/unx/source/dtrans/X11_selection.hxx
+++ b/vcl/unx/source/dtrans/X11_selection.hxx
@@ -32,6 +32,7 @@
#define _DTRANS_X11_SELECTION_HXX_
#include <cppuhelper/compbase3.hxx>
+#include <cppuhelper/compbase4.hxx>
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
#include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
@@ -39,6 +40,7 @@
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
#include <osl/thread.h>
#ifndef _OSL_CONDITION_HXX_
@@ -48,7 +50,9 @@
#include <hash_map>
#include <list>
+#include "tools/prex.h"
#include <X11/Xlib.h>
+#include "tools/postx.h"
#define XDND_IMPLEMENTATION_NAME "com.sun.star.datatransfer.dnd.XdndSupport"
#define XDND_DROPTARGET_IMPLEMENTATION_NAME "com.sun.star.datatransfer.dnd.XdndDropTarget"
@@ -84,7 +88,7 @@ namespace x11 {
::osl::Mutex m_aMutex;
bool m_bActive;
sal_Int8 m_nDefaultActions;
- Window m_aTargetWindow;
+ XLIB_Window m_aTargetWindow;
class SelectionManager* m_pSelectionManager;
Reference< ::com::sun::star::datatransfer::dnd::XDragSource >
m_xSelectionManager;
@@ -155,10 +159,11 @@ namespace x11 {
class SelectionManager :
- public ::cppu::WeakImplHelper3<
+ public ::cppu::WeakImplHelper4<
::com::sun::star::datatransfer::dnd::XDragSource,
::com::sun::star::lang::XInitialization,
- ::com::sun::star::awt::XEventHandler
+ ::com::sun::star::awt::XEventHandler,
+ ::com::sun::star::frame::XTerminateListener
>,
public SelectionAdaptor
{
@@ -175,7 +180,7 @@ namespace x11 {
{
Sequence< sal_Int8 > m_aData;
int m_nBufferPos;
- Window m_aRequestor;
+ XLIB_Window m_aRequestor;
Atom m_aProperty;
Atom m_aTarget;
int m_nFormat;
@@ -209,11 +214,11 @@ namespace x11 {
Atom m_aUTF8Type;
bool m_bHaveCompound;
bool m_bOwner;
- Window m_aLastOwner;
+ XLIB_Window m_aLastOwner;
PixmapHolder* m_pPixmap;
- // m_nOrigTimestamp contains the timestamp at which the seclection
- // was acquired; needed for TIMESTAMP target
- Time m_nOrigTimestamp;
+ // m_nOrigXLIB_Timestamp contains the XLIB_Timestamp at which the seclection
+ // was acquired; needed for XLIB_TimeSTAMP target
+ XLIB_Time m_nOrigTimestamp;
Selection() : m_eState( Inactive ),
m_pAdaptor( NULL ),
@@ -234,7 +239,7 @@ namespace x11 {
struct DropTargetEntry
{
DropTarget* m_pTarget;
- Window m_aRootWindow;
+ XLIB_Window m_aRootWindow;
DropTargetEntry() : m_pTarget( NULL ), m_aRootWindow( None ) {}
DropTargetEntry( DropTarget* pTarget ) :
@@ -257,13 +262,13 @@ namespace x11 {
oslThread m_aThread;
oslThread m_aDragExecuteThread;
::osl::Condition m_aDragRunning;
- Window m_aWindow;
+ XLIB_Window m_aWindow;
Reference< ::com::sun::star::awt::XDisplayConnection >
m_xDisplayConnection;
Reference< com::sun::star::script::XInvocation >
m_xBitmapConverter;
sal_Int32 m_nSelectionTimeout;
- Time m_nSelectionTimestamp;
+ XLIB_Time m_nSelectionTimestamp;
// members used for Xdnd
@@ -272,21 +277,21 @@ namespace x11 {
// contains the XdndEnterEvent of a drop action running
// with one of our targets. The data.l[0] member
- // (conatining the drag source window) is set
+ // (conatining the drag source XLIB_Window) is set
// to None while that is not the case
XClientMessageEvent m_aDropEnterEvent;
// set to false on XdndEnter
// set to true on first XdndPosition or XdndLeave
bool m_bDropEnterSent;
- Window m_aCurrentDropWindow;
- // time code of XdndDrop
- Time m_nDropTime;
+ XLIB_Window m_aCurrentDropWindow;
+ // XLIB_Time code of XdndDrop
+ XLIB_Time m_nDropTime;
sal_Int8 m_nLastDropAction;
// XTransferable for Xdnd with foreign drag source
Reference< ::com::sun::star::datatransfer::XTransferable >
m_xDropTransferable;
int m_nLastX, m_nLastY;
- Time m_nDropTimestamp;
+ XLIB_Time m_nDropTimestamp;
// set to true when calling drop()
// if another XdndEnter is received this shows that
// someone forgot to call dropComplete - we should reset
@@ -296,10 +301,10 @@ namespace x11 {
// drag only
// None if no Dnd action is running with us as source
- Window m_aDropWindow;
- // either m_aDropWindow or its XdndProxy
- Window m_aDropProxy;
- Window m_aDragSourceWindow;
+ XLIB_Window m_aDropWindow;
+ // either m_aDropXLIB_Window or its XdndProxy
+ XLIB_Window m_aDropProxy;
+ XLIB_Window m_aDragSourceWindow;
// XTransferable for Xdnd when we are drag source
Reference< ::com::sun::star::datatransfer::XTransferable >
m_xDragSourceTransferable;
@@ -321,20 +326,20 @@ namespace x11 {
bool m_bDropSent;
time_t m_nDropTimeout;
bool m_bWaitingForPrimaryConversion;
- Time m_nDragTimestamp;
+ XLIB_Time m_nDragTimestamp;
// drag cursors
- Cursor m_aMoveCursor;
- Cursor m_aCopyCursor;
- Cursor m_aLinkCursor;
- Cursor m_aNoneCursor;
- Cursor m_aCurrentCursor;
+ XLIB_Cursor m_aMoveCursor;
+ XLIB_Cursor m_aCopyCursor;
+ XLIB_Cursor m_aLinkCursor;
+ XLIB_Cursor m_aNoneCursor;
+ XLIB_Cursor m_aCurrentCursor;
// drag and drop
int m_nCurrentProtocolVersion;
- ::std::hash_map< Window, DropTargetEntry >
+ ::std::hash_map< XLIB_Window, DropTargetEntry >
m_aDropTargets;
@@ -374,7 +379,7 @@ namespace x11 {
::std::hash_map< Atom, Selection* >
m_aSelections;
// IncrementalTransfers in progress
- std::hash_map< Window, std::hash_map< Atom, IncrementalTransfer > >
+ std::hash_map< XLIB_Window, std::hash_map< Atom, IncrementalTransfer > >
m_aIncrementals;
// do not use X11 multithreading capabilities
@@ -398,12 +403,12 @@ namespace x11 {
// dnd helpers
void sendDragStatus( Atom nDropAction );
- void sendDropPosition( bool bForce, Time eventTime );
+ void sendDropPosition( bool bForce, XLIB_Time eventXLIB_Time );
bool updateDragAction( int modifierState );
- int getXdndVersion( Window aWindow, Window& rProxy );
- Cursor createCursor( const char* pPointerData, const char* pMaskData, int width, int height, int hotX, int hotY );
- // coordinates on root window
- void updateDragWindow( int nX, int nY, Window aRoot );
+ int getXdndVersion( XLIB_Window aXLIB_Window, XLIB_Window& rProxy );
+ XLIB_Cursor createCursor( const char* pPointerData, const char* pMaskData, int width, int height, int hotX, int hotY );
+ // coordinates on root XLIB_Window
+ void updateDragWindow( int nX, int nY, XLIB_Window aRoot );
bool getPasteData( Atom selection, Atom type, Sequence< sal_Int8 >& rData );
// returns true if conversion was successful
@@ -412,7 +417,7 @@ namespace x11 {
Atom nSelection,
int & rFormat,
Sequence< sal_Int8 >& rData );
- bool sendData( SelectionAdaptor* pAdaptor, Window requestor, Atom target, Atom property, Atom selection );
+ bool sendData( SelectionAdaptor* pAdaptor, XLIB_Window requestor, Atom target, Atom property, Atom selection );
// thread dispatch loop
public:
@@ -438,7 +443,7 @@ namespace x11 {
static SelectionManager& get( const ::rtl::OUString& rDisplayName = ::rtl::OUString() );
Display * getDisplay() { return m_pDisplay; };
- Window getWindow() { return m_aWindow; };
+ XLIB_Window getWindow() { return m_aWindow; };
void registerHandler( Atom selection, SelectionAdaptor& rAdaptor );
@@ -464,20 +469,22 @@ namespace x11 {
bool getPasteData( Atom selection, const ::rtl::OUString& rType, Sequence< sal_Int8 >& rData );
// for XDropTarget to register/deregister itself
- void registerDropTarget( Window aWindow, DropTarget* pTarget );
- void deregisterDropTarget( Window aWindow );
+ void registerDropTarget( XLIB_Window aXLIB_Window, DropTarget* pTarget );
+ void deregisterDropTarget( XLIB_Window aXLIB_Window );
// for XDropTarget{Drag|Drop}Context
- void accept( sal_Int8 dragOperation, Window aDropWindow, Time aTimestamp );
- void reject( Window aDropWindow, Time aTimestamp );
- void dropComplete( sal_Bool success, Window aDropWindow, Time aTimestamp );
+ void accept( sal_Int8 dragOperation, XLIB_Window aDropXLIB_Window, XLIB_Time aXLIB_Timestamp );
+ void reject( XLIB_Window aDropXLIB_Window, XLIB_Time aXLIB_Timestamp );
+ void dropComplete( sal_Bool success, XLIB_Window aDropXLIB_Window, XLIB_Time aXLIB_Timestamp );
// for XDragSourceContext
sal_Int32 getCurrentCursor();
- void setCursor( sal_Int32 cursor, Window aDropWindow, Time aTimestamp );
- void setImage( sal_Int32 image, Window aDropWindow, Time aTimestamp );
+ void setCursor( sal_Int32 cursor, XLIB_Window aDropXLIB_Window, XLIB_Time aXLIB_Timestamp );
+ void setImage( sal_Int32 image, XLIB_Window aDropXLIB_Window, XLIB_Time aXLIB_Timestamp );
void transferablesFlavorsChanged();
+ void shutdown() throw();
+
// XInitialization
virtual void SAL_CALL initialize( const Sequence< Any >& arguments ) throw( ::com::sun::star::uno::Exception );
@@ -499,6 +506,15 @@ namespace x11 {
virtual void clearTransferable() throw();
virtual void fireContentsChanged() throw();
virtual Reference< XInterface > getReference() throw();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw( ::com::sun::star::uno::RuntimeException );
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent )
+ throw( ::com::sun::star::uno::RuntimeException );
};
// ------------------------------------------------------------------------
diff --git a/vcl/unx/source/dtrans/bmp.cxx b/vcl/unx/source/dtrans/bmp.cxx
index 49219bfb0e2a..f3c7d78617a6 100644
--- a/vcl/unx/source/dtrans/bmp.cxx
+++ b/vcl/unx/source/dtrans/bmp.cxx
@@ -356,7 +356,7 @@ sal_uInt8* x11::X11_getBmpFromPixmap(
)
{
// get geometry of drawable
- Window aRoot;
+ XLIB_Window aRoot;
int x,y;
unsigned int w, h, bw, d;
XGetGeometry( pDisplay, aDrawable, &aRoot, &x, &y, &w, &h, &bw, &d );
diff --git a/vcl/unx/source/dtrans/bmp.hxx b/vcl/unx/source/dtrans/bmp.hxx
index baf04ac31d90..6331122e726d 100644
--- a/vcl/unx/source/dtrans/bmp.hxx
+++ b/vcl/unx/source/dtrans/bmp.hxx
@@ -31,10 +31,12 @@
#ifndef _DTRANS_BMP_HXX_
#define _DTRANS_BMP_HXX_
+#include "tools/prex.h"
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#include "tools/postx.h"
#include <sal/types.h>
#include <com/sun/star/awt/XBitmap.hpp>
diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx
index 5fe2295a8fed..386be14f04d7 100644
--- a/vcl/unx/source/gdi/salgdi.cxx
+++ b/vcl/unx/source/gdi/salgdi.cxx
@@ -1428,14 +1428,17 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
// unless it splits another trapezoid that is still active
bool bSplit = false;
ActiveTrapSet::iterator aActiveTrapsIt = aActiveTraps.begin();
- for(; aActiveTrapsIt != aActiveTraps.end(); ++aActiveTrapsIt )
+ while(aActiveTrapsIt != aActiveTraps.end())
{
XTrapezoid& rLeftTrap = aTrapVector[ *aActiveTrapsIt ];
// skip until first overlap candidate
// TODO: use stl::*er_bound() instead
if( IsLeftOf( aTrapezoid.left, rLeftTrap.left) )
+ {
+ ++aActiveTrapsIt;
continue;
+ }
// in the ActiveTrapSet there are still trapezoids where
// a vertical overlap with new trapezoids is no longer possible
@@ -1446,15 +1449,26 @@ bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rOrigPoly
{
ActiveTrapSet::iterator it = aActiveTrapsIt;
if( aActiveTrapsIt != aActiveTraps.begin() )
+ {
--aActiveTrapsIt;
- aActiveTraps.erase( it );
+ aActiveTraps.erase( it );
+ ++aActiveTrapsIt;
+ }
+ else
+ {
+ aActiveTraps.erase( it );
+ aActiveTrapsIt = aActiveTraps.begin();
+ }
continue;
}
// check if there is horizontal overlap
// aTrapezoid.left==rLeftTrap.right is allowed though
if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) )
+ {
+ ++aActiveTrapsIt;
continue;
+ }
// prepare to split the old trapezoid and keep its upper part
// find the old trapezoids entry in the VerticalTrapSet and remove it
diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx
index d47e30a89633..4dc9a0b6a455 100644
--- a/vcl/unx/source/gdi/salprnpsp.cxx
+++ b/vcl/unx/source/gdi/salprnpsp.cxx
@@ -839,7 +839,7 @@ String PspSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, ULONG
{
const PPDValue* pValue = pKey->getValue( nPaperBin );
if( pValue )
- aRet = pValue->m_aOptionTranslation.Len() ? pValue->m_aOptionTranslation : pValue->m_aOption;
+ aRet = aData.m_pParser->translateOption( pKey->getKey(), pValue->m_aOption );
}
}
diff --git a/vcl/unx/source/printer/cupsmgr.cxx b/vcl/unx/source/printer/cupsmgr.cxx
index d0c7f184fb06..4c38479f1107 100644
--- a/vcl/unx/source/printer/cupsmgr.cxx
+++ b/vcl/unx/source/printer/cupsmgr.cxx
@@ -533,6 +533,10 @@ void CUPSManager::initialize()
pDest->options );
if( pOpt )
m_bUseIncludeFeature = true;
+ // do not send include JobPatch; CUPS will insert that itself
+ // TODO: currently unknwon which versions of CUPS insert JobPatches
+ // so currently it is assumed CUPS = don't insert JobPatch files
+ m_bUseJobPatch = false;
rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
int nPrinter = m_nDests;
diff --git a/vcl/unx/source/printer/ppdparser.cxx b/vcl/unx/source/printer/ppdparser.cxx
index 95bc7bca41ca..a70a5ac7f6c8 100644
--- a/vcl/unx/source/printer/ppdparser.cxx
+++ b/vcl/unx/source/printer/ppdparser.cxx
@@ -39,6 +39,7 @@
#include "vcl/ppdparser.hxx"
#include "vcl/strhelper.hxx"
#include "vcl/helper.hxx"
+#include "vcl/svapp.hxx"
#include "cupsmgr.hxx"
#include "tools/debug.hxx"
#include "tools/urlobj.hxx"
@@ -51,6 +52,202 @@
#include "rtl/strbuf.hxx"
#include "rtl/ustrbuf.hxx"
+#include "com/sun/star/lang/Locale.hpp"
+
+namespace psp
+{
+ class PPDTranslator
+ {
+ struct LocaleEqual
+ {
+ bool operator()(const com::sun::star::lang::Locale& i_rLeft,
+ const com::sun::star::lang::Locale& i_rRight) const
+ {
+ return i_rLeft.Language.equals( i_rRight.Language ) &&
+ i_rLeft.Country.equals( i_rRight.Country ) &&
+ i_rLeft.Variant.equals( i_rRight.Variant );
+ }
+ };
+
+ struct LocaleHash
+ {
+ size_t operator()(const com::sun::star::lang::Locale& rLocale) const
+ { return
+ (size_t)rLocale.Language.hashCode()
+ ^ (size_t)rLocale.Country.hashCode()
+ ^ (size_t)rLocale.Variant.hashCode()
+ ;
+ }
+ };
+
+ typedef std::hash_map< com::sun::star::lang::Locale, rtl::OUString, LocaleHash, LocaleEqual > translation_map;
+ typedef std::hash_map< rtl::OUString, translation_map, rtl::OUStringHash > key_translation_map;
+
+ key_translation_map m_aTranslations;
+ public:
+ PPDTranslator() {}
+ ~PPDTranslator() {}
+
+
+ void insertValue(
+ const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rValue,
+ const rtl::OUString& i_rTranslation,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale()
+ );
+
+ void insertOption( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rTranslation,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() )
+ {
+ insertValue( i_rKey, i_rOption, rtl::OUString(), i_rTranslation, i_rLocale );
+ }
+
+ void insertKey( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rTranslation,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() )
+ {
+ insertValue( i_rKey, rtl::OUString(), rtl::OUString(), i_rTranslation, i_rLocale );
+ }
+
+ rtl::OUString translateValue(
+ const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rValue,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale()
+ ) const;
+
+ rtl::OUString translateOption( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const
+ {
+ return translateValue( i_rKey, i_rOption, rtl::OUString(), i_rLocale );
+ }
+
+ rtl::OUString translateKey( const rtl::OUString& i_rKey,
+ const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const
+ {
+ return translateValue( i_rKey, rtl::OUString(), rtl::OUString(), i_rLocale );
+ }
+ };
+
+ static com::sun::star::lang::Locale normalizeInputLocale(
+ const com::sun::star::lang::Locale& i_rLocale,
+ bool bInsertDefault = false
+ )
+ {
+ com::sun::star::lang::Locale aLoc( i_rLocale );
+ if( bInsertDefault && aLoc.Language.getLength() == 0 )
+ {
+ // empty locale requested, fill in application UI locale
+ aLoc = Application::GetSettings().GetUILocale();
+
+ #if OSL_DEBUG_LEVEL > 1
+ static const char* pEnvLocale = getenv( "SAL_PPDPARSER_LOCALE" );
+ if( pEnvLocale && *pEnvLocale )
+ {
+ rtl::OString aStr( pEnvLocale );
+ sal_Int32 nLen = aStr.getLength();
+ aLoc.Language = rtl::OStringToOUString( aStr.copy( 0, nLen > 2 ? 2 : nLen ), RTL_TEXTENCODING_MS_1252 );
+ if( nLen >=5 && aStr.getStr()[2] == '_' )
+ aLoc.Country = rtl::OStringToOUString( aStr.copy( 3, 2 ), RTL_TEXTENCODING_MS_1252 );
+ else
+ aLoc.Country = rtl::OUString();
+ aLoc.Variant = rtl::OUString();
+ }
+ #endif
+ }
+ aLoc.Language = aLoc.Language.toAsciiLowerCase();
+ aLoc.Country = aLoc.Country.toAsciiUpperCase();
+ aLoc.Variant = aLoc.Variant.toAsciiUpperCase();
+
+ return aLoc;
+ }
+
+ void PPDTranslator::insertValue(
+ const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rValue,
+ const rtl::OUString& i_rTranslation,
+ const com::sun::star::lang::Locale& i_rLocale
+ )
+ {
+ rtl::OUStringBuffer aKey( i_rKey.getLength() + i_rOption.getLength() + i_rValue.getLength() + 2 );
+ aKey.append( i_rKey );
+ if( i_rOption.getLength() || i_rValue.getLength() )
+ {
+ aKey.append( sal_Unicode( ':' ) );
+ aKey.append( i_rOption );
+ }
+ if( i_rValue.getLength() )
+ {
+ aKey.append( sal_Unicode( ':' ) );
+ aKey.append( i_rValue );
+ }
+ if( aKey.getLength() && i_rTranslation.getLength() )
+ {
+ rtl::OUString aK( aKey.makeStringAndClear() );
+ com::sun::star::lang::Locale aLoc;
+ aLoc.Language = i_rLocale.Language.toAsciiLowerCase();
+ aLoc.Country = i_rLocale.Country.toAsciiUpperCase();
+ aLoc.Variant = i_rLocale.Variant.toAsciiUpperCase();
+ m_aTranslations[ aK ][ aLoc ] = i_rTranslation;
+ }
+ }
+
+ rtl::OUString PPDTranslator::translateValue(
+ const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rValue,
+ const com::sun::star::lang::Locale& i_rLocale
+ ) const
+ {
+ rtl::OUString aResult;
+
+ rtl::OUStringBuffer aKey( i_rKey.getLength() + i_rOption.getLength() + i_rValue.getLength() + 2 );
+ aKey.append( i_rKey );
+ if( i_rOption.getLength() || i_rValue.getLength() )
+ {
+ aKey.append( sal_Unicode( ':' ) );
+ aKey.append( i_rOption );
+ }
+ if( i_rValue.getLength() )
+ {
+ aKey.append( sal_Unicode( ':' ) );
+ aKey.append( i_rValue );
+ }
+ if( aKey.getLength() )
+ {
+ rtl::OUString aK( aKey.makeStringAndClear() );
+ key_translation_map::const_iterator it = m_aTranslations.find( aK );
+ if( it != m_aTranslations.end() )
+ {
+ const translation_map& rMap( it->second );
+
+ com::sun::star::lang::Locale aLoc( normalizeInputLocale( i_rLocale, true ) );
+ for( int nTry = 0; nTry < 4; nTry++ )
+ {
+ translation_map::const_iterator tr = rMap.find( aLoc );
+ if( tr != rMap.end() )
+ {
+ aResult = tr->second;
+ break;
+ }
+ switch( nTry )
+ {
+ case 0: aLoc.Variant = rtl::OUString();break;
+ case 1: aLoc.Country = rtl::OUString();break;
+ case 2: aLoc.Language = rtl::OUString();break;
+ }
+ }
+ }
+ }
+ return aResult;
+ }
+}
+
using namespace psp;
using namespace rtl;
@@ -481,7 +678,8 @@ PPDParser::PPDParser( const String& rFile ) :
m_pResolutions( NULL ),
m_pDefaultDuplexType( NULL ),
m_pDuplexTypes( NULL ),
- m_pFontList( NULL )
+ m_pFontList( NULL ),
+ m_pTranslator( new PPDTranslator() )
{
// read in the file
std::list< ByteString > aLines;
@@ -648,6 +846,7 @@ PPDParser::~PPDParser()
{
for( PPDParser::hash_type::iterator it = m_aKeys.begin(); it != m_aKeys.end(); ++it )
delete it->second;
+ delete m_pTranslator;
}
void PPDParser::insertKey( const String& rKey, PPDKey* pKey )
@@ -687,11 +886,11 @@ static sal_uInt8 getNibble( sal_Char cChar )
return nRet;
}
-String PPDParser::handleTranslation( const ByteString& rString )
+String PPDParser::handleTranslation( const ByteString& i_rString, bool bIsGlobalized )
{
- int nOrigLen = rString.Len();
+ int nOrigLen = i_rString.Len();
OStringBuffer aTrans( nOrigLen );
- const sal_Char* pStr = rString.GetBuffer();
+ const sal_Char* pStr = i_rString.GetBuffer();
const sal_Char* pEnd = pStr + nOrigLen;
while( pStr < pEnd )
{
@@ -710,14 +909,11 @@ String PPDParser::handleTranslation( const ByteString& rString )
else
aTrans.append( *pStr++ );
}
- return OStringToOUString( aTrans.makeStringAndClear(), m_aFileEncoding );
+ return OStringToOUString( aTrans.makeStringAndClear(), bIsGlobalized ? RTL_TEXTENCODING_UTF8 : m_aFileEncoding );
}
void PPDParser::parse( ::std::list< ByteString >& rLines )
{
- PPDValue* pValue = NULL;
- PPDKey* pKey = NULL;
-
std::list< ByteString >::iterator line = rLines.begin();
PPDParser::hash_type::const_iterator keyit;
while( line != rLines.end() )
@@ -765,14 +961,25 @@ void PPDParser::parse( ::std::list< ByteString >& rLines )
}
String aUniKey( aKey, RTL_TEXTENCODING_MS_1252 );
- keyit = m_aKeys.find( aUniKey );
- if( keyit == m_aKeys.end() )
+ // handle CUPS extension for globalized PPDs
+ bool bIsGlobalizedLine = false;
+ com::sun::star::lang::Locale aTransLocale;
+ if( ( aUniKey.Len() > 3 && aUniKey.GetChar( 2 ) == '.' ) ||
+ ( aUniKey.Len() > 5 && aUniKey.GetChar( 2 ) == '_' && aUniKey.GetChar( 5 ) == '.' ) )
{
- pKey = new PPDKey( aUniKey );
- insertKey( aUniKey, pKey );
+ if( aUniKey.GetChar( 2 ) == '.' )
+ {
+ aTransLocale.Language = aUniKey.Copy( 0, 2 );
+ aUniKey = aUniKey.Copy( 3 );
+ }
+ else
+ {
+ aTransLocale.Language = aUniKey.Copy( 0, 2 );
+ aTransLocale.Country = aUniKey.Copy( 3, 2 );
+ aUniKey = aUniKey.Copy( 6 );
+ }
+ bIsGlobalizedLine = true;
}
- else
- pKey = keyit->second;
String aOption;
nPos = aCurrentLine.Search( ':' );
@@ -784,76 +991,125 @@ void PPDParser::parse( ::std::list< ByteString >& rLines )
if( nTransPos != STRING_NOTFOUND )
aOption.Erase( nTransPos );
}
- pValue = pKey->insertValue( aOption );
- if( ! pValue )
- continue;
- if( nPos == STRING_NOTFOUND )
+ PPDValueType eType = eNo;
+ String aValue;
+ rtl::OUString aOptionTranslation;
+ rtl::OUString aValueTranslation;
+ if( nPos != STRING_NOTFOUND )
{
- // have a single main keyword
- pValue->m_eType = eNo;
- if( bQuery )
- pKey->eraseValue( aOption );
- continue;
- }
+ // found a colon, there may be an option
+ ByteString aLine = aCurrentLine.Copy( 1, nPos-1 );
+ aLine = WhitespaceToSpace( aLine );
+ int nTransPos = aLine.Search( '/' );
+ if( nTransPos != STRING_NOTFOUND )
+ aOptionTranslation = handleTranslation( aLine.Copy( nTransPos+1 ), bIsGlobalizedLine );
- // found a colon, there may be an option
- ByteString aLine = aCurrentLine.Copy( 1, nPos-1 );
- aLine = WhitespaceToSpace( aLine );
- int nTransPos = aLine.Search( '/' );
- if( nTransPos != STRING_NOTFOUND )
- pValue->m_aOptionTranslation = handleTranslation( aLine.Copy( nTransPos+1 ) );
-
- // read in more lines if necessary for multiline values
- aLine = aCurrentLine.Copy( nPos+1 );
- while( ! ( aLine.GetTokenCount( '"' ) & 1 ) &&
- line != rLines.end() )
- // while there is an even number of tokens; that m_eans
- // an odd number of doubleqoutes
- {
- // copy the newlines also
- aLine += '\n';
- aLine += *line;
- ++line;
+ // read in more lines if necessary for multiline values
+ aLine = aCurrentLine.Copy( nPos+1 );
+ if( aLine.Len() )
+ {
+ while( ! ( aLine.GetTokenCount( '"' ) & 1 ) &&
+ line != rLines.end() )
+ // while there is an even number of tokens; that means
+ // an odd number of doubleqoutes
+ {
+ // copy the newlines also
+ aLine += '\n';
+ aLine += *line;
+ ++line;
+ }
+ }
+ aLine = WhitespaceToSpace( aLine );
+
+ // #i100644# handle a missing value (actually a broken PPD)
+ if( ! aLine.Len() )
+ {
+ if( aOption.Len() &&
+ aUniKey.CompareToAscii( "JCL", 3 ) != COMPARE_EQUAL )
+ eType = eInvocation;
+ else
+ eType = eQuoted;
+ }
+ // check for invocation or quoted value
+ else if( aLine.GetChar(0) == '"' )
+ {
+ aLine.Erase( 0, 1 );
+ nTransPos = aLine.Search( '"' );
+ aValue = String( aLine.Copy( 0, nTransPos ), RTL_TEXTENCODING_MS_1252 );
+ // after the second doublequote can follow a / and a translation
+ aValueTranslation = handleTranslation( aLine.Copy( nTransPos+2 ), bIsGlobalizedLine );
+ // check for quoted value
+ if( aOption.Len() &&
+ aUniKey.CompareToAscii( "JCL", 3 ) != COMPARE_EQUAL )
+ eType = eInvocation;
+ else
+ eType = eQuoted;
+ }
+ // check for symbol value
+ else if( aLine.GetChar(0) == '^' )
+ {
+ aLine.Erase( 0, 1 );
+ aValue = String( aLine, RTL_TEXTENCODING_MS_1252 );
+ eType = eSymbol;
+ }
+ else
+ {
+ // must be a string value then
+ // strictly this is false because string values
+ // can contain any whitespace which is reduced
+ // to one space by now
+ // who cares ...
+ nTransPos = aLine.Search( '/' );
+ if( nTransPos == STRING_NOTFOUND )
+ nTransPos = aLine.Len();
+ aValue = String( aLine.Copy( 0, nTransPos ), RTL_TEXTENCODING_MS_1252 );
+ aValueTranslation = handleTranslation( aLine.Copy( nTransPos+1 ), bIsGlobalizedLine );
+ eType = eString;
+ }
}
- aLine = WhitespaceToSpace( aLine );
- // check for invocation or quoted value
- if( aLine.GetChar(0) == '"' )
+ // handle globalized PPD entries
+ if( bIsGlobalizedLine )
{
- aLine.Erase( 0, 1 );
- nTransPos = aLine.Search( '"' );
- pValue->m_aValue = String( aLine.Copy( 0, nTransPos ), RTL_TEXTENCODING_MS_1252 );
- // after the second doublequote can follow a / and a translation
- pValue->m_aValueTranslation = handleTranslation( aLine.Copy( nTransPos+2 ) );
- // check for quoted value
- if( pValue->m_aOption.Len() &&
- aKey.CompareTo( "JCL", 3 ) != COMPARE_EQUAL )
- pValue->m_eType = eInvocation;
+ // handle main key translations of form:
+ // *ll_CC.Translation MainKeyword/translated text: ""
+ if( aUniKey.EqualsAscii( "Translation" ) )
+ {
+ m_pTranslator->insertKey( aOption, aOptionTranslation, aTransLocale );
+ }
+ // handle options translations of for:
+ // *ll_CC.MainKeyword OptionKeyword/translated text: ""
else
- pValue->m_eType = eQuoted;
+ {
+ m_pTranslator->insertOption( aUniKey, aOption, aOptionTranslation, aTransLocale );
+ }
+ continue;
}
- // check for symbol value
- else if( aLine.GetChar(0) == '^' )
+
+ PPDKey* pKey = NULL;
+ keyit = m_aKeys.find( aUniKey );
+ if( keyit == m_aKeys.end() )
{
- aLine.Erase( 0, 1 );
- pValue->m_aValue = String( aLine, RTL_TEXTENCODING_MS_1252 );
- pValue->m_eType = eSymbol;
+ pKey = new PPDKey( aUniKey );
+ insertKey( aUniKey, pKey );
}
else
- {
- // must be a string value then
- // strictly this is false because string values
- // can contain any whitespace which is reduced
- // to one space by now
- // who cares ...
- nTransPos = aLine.Search( '/' );
- if( nTransPos == STRING_NOTFOUND )
- nTransPos = aLine.Len();
- pValue->m_aValue = String( aLine.Copy( 0, nTransPos ), RTL_TEXTENCODING_MS_1252 );
- pValue->m_aValueTranslation = handleTranslation( aLine.Copy( nTransPos+1 ) );
- pValue->m_eType = eString;
- }
+ pKey = keyit->second;
+
+ if( eType == eNo && bQuery )
+ continue;
+
+ PPDValue* pValue = pKey->insertValue( aOption );
+ if( ! pValue )
+ continue;
+ pValue->m_eType = eType;
+ pValue->m_aValue = aValue;
+
+ if( aOptionTranslation.getLength() )
+ m_pTranslator->insertOption( aUniKey, aOption, aOptionTranslation, aTransLocale );
+ if( aValueTranslation.getLength() )
+ m_pTranslator->insertValue( aUniKey, aOption, aValue, aValueTranslation, aTransLocale );
// eventually update query and remove from option list
if( bQuery && pKey->m_bQueryValue == FALSE )
@@ -879,7 +1135,7 @@ void PPDParser::parse( ::std::list< ByteString >& rLines )
keyit = m_aKeys.find( aKey );
if( keyit != m_aKeys.end() )
{
- pKey = keyit->second;
+ PPDKey* pKey = keyit->second;
const PPDValue* pDefValue = pKey->getValue( aOption );
if( pKey->m_pDefaultValue == NULL )
pKey->m_pDefaultValue = pDefValue;
@@ -890,7 +1146,7 @@ void PPDParser::parse( ::std::list< ByteString >& rLines )
// do not exist otherwise
// (example: DefaultResolution)
// so invent that key here and have a default value
- pKey = new PPDKey( aKey );
+ PPDKey* pKey = new PPDKey( aKey );
PPDValue* pNewValue = pKey->insertValue( aOption );
pNewValue->m_eType = eInvocation; // or what ?
insertKey( aKey, pKey );
@@ -915,7 +1171,7 @@ void PPDParser::parseOpenUI( const ByteString& rLine )
nPos = aKey.Search( '/' );
if( nPos != STRING_NOTFOUND )
{
- aTranslation = handleTranslation( aKey.Copy( nPos + 1 ) );
+ aTranslation = handleTranslation( aKey.Copy( nPos + 1 ), false );
aKey.Erase( nPos );
}
aKey = GetCommandLineToken( 1, aKey );
@@ -933,7 +1189,7 @@ void PPDParser::parseOpenUI( const ByteString& rLine )
pKey = keyit->second;
pKey->m_bUIOption = true;
- pKey->m_aUITranslation = aTranslation;
+ m_pTranslator->insertKey( pKey->getKey(), aTranslation );
ByteString aValue = WhitespaceToSpace( rLine.GetToken( 1, ':' ) );
if( aValue.CompareIgnoreCaseToAscii( "boolean" ) == COMPARE_EQUAL )
@@ -1393,6 +1649,36 @@ const String& PPDParser::getFont( int nFont ) const
return aEmptyString;
}
+rtl::OUString PPDParser::translateKey( const rtl::OUString& i_rKey,
+ const com::sun::star::lang::Locale& i_rLocale ) const
+{
+ rtl::OUString aResult( m_pTranslator->translateKey( i_rKey, i_rLocale ) );
+ if( aResult.getLength() == 0 )
+ aResult = i_rKey;
+ return aResult;
+}
+
+rtl::OUString PPDParser::translateOption( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const com::sun::star::lang::Locale& i_rLocale ) const
+{
+ rtl::OUString aResult( m_pTranslator->translateOption( i_rKey, i_rOption, i_rLocale ) );
+ if( aResult.getLength() == 0 )
+ aResult = i_rOption;
+ return aResult;
+}
+
+rtl::OUString PPDParser::translateValue( const rtl::OUString& i_rKey,
+ const rtl::OUString& i_rOption,
+ const rtl::OUString& i_rValue,
+ const com::sun::star::lang::Locale& i_rLocale ) const
+{
+ rtl::OUString aResult( m_pTranslator->translateValue( i_rKey, i_rOption, i_rValue, i_rLocale ) );
+ if( aResult.getLength() == 0 )
+ aResult = i_rValue;
+ return aResult;
+}
+
/*
* PPDKey
*/
diff --git a/vcl/unx/source/printer/printerinfomanager.cxx b/vcl/unx/source/printer/printerinfomanager.cxx
index 53cd662db8e0..ef6a67203cd8 100644
--- a/vcl/unx/source/printer/printerinfomanager.cxx
+++ b/vcl/unx/source/printer/printerinfomanager.cxx
@@ -119,6 +119,7 @@ PrinterInfoManager::PrinterInfoManager( Type eType ) :
m_pQueueInfo( NULL ),
m_eType( eType ),
m_bUseIncludeFeature( false ),
+ m_bUseJobPatch( true ),
m_aSystemDefaultPaper( RTL_CONSTASCII_USTRINGPARAM( "A4" ) ),
m_bDisableCUPS( false )
{
diff --git a/vcl/unx/source/printergfx/printerjob.cxx b/vcl/unx/source/printergfx/printerjob.cxx
index 1c42cafa4cb9..bc9746c3fe77 100644
--- a/vcl/unx/source/printergfx/printerjob.cxx
+++ b/vcl/unx/source/printergfx/printerjob.cxx
@@ -915,6 +915,9 @@ bool PrinterJob::writePageSetup( osl::File* pFile, const JobData& rJob, bool bWr
void PrinterJob::writeJobPatch( osl::File* pFile, const JobData& rJobData )
{
+ if( ! PrinterInfoManager::get().getUseJobPatch() )
+ return;
+
const PPDKey* pKey = NULL;
if( rJobData.m_pParser )
diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk
index c5a99d47c709..72ffd89bd6ed 100644
--- a/vcl/util/makefile.mk
+++ b/vcl/util/makefile.mk
@@ -303,6 +303,7 @@ SHL2STDLIBS=\
$(VOSLIB) \
$(BASEGFXLIB) \
$(UNOTOOLSLIB) \
+ $(COMPHELPERLIB) \
$(CPPUHELPERLIB) \
$(CPPULIB) \
$(SALLIB)
diff --git a/vcl/util/makefile2.pmk b/vcl/util/makefile2.pmk
index 63b2889bc15d..cb13e3b42743 100644
--- a/vcl/util/makefile2.pmk
+++ b/vcl/util/makefile2.pmk
@@ -36,3 +36,10 @@ VISIBILITY_HIDDEN=TRUE
.IF "$(GUIBASE)"=="aqua"
CFLAGSCXX+=$(OBJCXXFLAGS)
.ENDIF # "$(GUIBASE)"=="aqua"
+
+#building with stlport, but graphite was not built with stlport
+.IF "$(USE_SYSTEM_STL)"!="YES"
+.IF "$(SYSTEM_GRAPHITE)"=="YES"
+CDEFS += -DGRAPHITEADAPTSTL
+.ENDIF
+.ENDIF
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
index fc92757e0925..8bbd32994dec 100644..100755
--- a/vcl/win/source/window/salframe.cxx
+++ b/vcl/win/source/window/salframe.cxx
@@ -2978,6 +2978,11 @@ void WinSalFrame::UpdateSettings( AllSettings& rSettings )
aStyleSettings.SetCheckedColor( Color( nRed, nGreen, nBlue ) );
}
+ // caret width
+ DWORD nCaretWidth = 2;
+ if( SystemParametersInfo( SPI_GETCARETWIDTH, 0, &nCaretWidth, 0 ) )
+ aStyleSettings.SetCursorSize( nCaretWidth );
+
// High contrast
HIGHCONTRAST hc;
hc.cbSize = sizeof( HIGHCONTRAST );