summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorMathias Bauer <mba@openoffice.org>2009-10-19 13:22:39 +0200
committerMathias Bauer <mba@openoffice.org>2009-10-19 13:22:39 +0200
commit942dbe34b9a1400c926a81f88e849d248b58ed55 (patch)
tree0fe108618106e42e0a25074782c160c393b45ffb /unotools
parentc5ddee96afdc3ceb5bcc023b36185122a16b283d (diff)
#i103496#: move some fontsubstitution stuff from vcl to unotools to get xmloff vcl free
Diffstat (limited to 'unotools')
-rw-r--r--unotools/inc/unotools/fontcfg.hxx230
-rw-r--r--unotools/inc/unotools/fontcvt.hxx82
-rw-r--r--unotools/inc/unotools/fontdefs.hxx110
-rw-r--r--unotools/source/config/fontcfg.cxx1220
-rw-r--r--unotools/source/config/makefile.mk1
-rw-r--r--unotools/source/misc/fontcvt.cxx1523
-rw-r--r--unotools/source/misc/fontdefs.cxx596
-rw-r--r--unotools/source/misc/makefile.mk2
8 files changed, 3764 insertions, 0 deletions
diff --git a/unotools/inc/unotools/fontcfg.hxx b/unotools/inc/unotools/fontcfg.hxx
new file mode 100644
index 000000000000..4d0ed4036328
--- /dev/null
+++ b/unotools/inc/unotools/fontcfg.hxx
@@ -0,0 +1,230 @@
+/*************************************************************************
+ *
+ * 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: fontcfg.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 _UNOTOOLS_FONTCFG_HXX
+#define _UNOTOOLS_FONTCFG_HXX
+
+#include <unotools/unotoolsdllapi.h>
+#include <tools/string.hxx>
+#include <tools/fontenum.hxx>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <hash_map>
+#include <hash_set>
+#include <vector>
+
+namespace com {
+namespace sun {
+namespace star {
+namespace lang {
+
+// equality operator needed for hash_map;
+// (-> why does this need to be in the namespace of Locale ? g++ fails to compile else)
+inline bool operator==( const com::sun::star::lang::Locale& rLeft, const com::sun::star::lang::Locale& rRight )
+{
+ return
+ rLeft.Language.equals( rRight.Language ) &&
+ rLeft.Country.equals( rRight.Country ) &&
+ rLeft.Variant.equals( rRight.Variant )
+ ;
+}
+}}}}
+
+namespace utl
+{
+
+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();
+ }
+};
+
+class UNOTOOLS_DLLPUBLIC DefaultFontConfiguration
+{
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ m_xConfigProvider;
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
+ m_xConfigAccess;
+
+ struct LocaleAccess
+ {
+ // the real string used in the configuration
+ // used to get rid of upper/lower case problems
+ rtl::OUString aConfigLocaleString;
+ // xAccess is mutable to be able to be filled on demand
+ mutable com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xAccess;
+ };
+
+ std::hash_map< com::sun::star::lang::Locale,
+ LocaleAccess,
+ utl::LocaleHash >
+ m_aConfig;
+
+ rtl::OUString tryLocale( const com::sun::star::lang::Locale& rLocale, const rtl::OUString& rType ) const;
+
+ DefaultFontConfiguration();
+ public:
+ ~DefaultFontConfiguration();
+
+ static DefaultFontConfiguration* get();
+
+ rtl::OUString getDefaultFont( const com::sun::star::lang::Locale& rLocale, int nType ) const;
+ rtl::OUString getUserInterfaceFont( const com::sun::star::lang::Locale& rLocale ) const;
+};
+
+// IMPL_FONT_ATTR_DEFAULT - Default-Font like Andale Sans UI, Palace Script, Albany, Thorndale, Cumberland, ...
+// IMPL_FONT_ATTR_STANDARD - Standard-Font like Arial, Times, Courier, ...
+// IMPL_FONT_ATTR_NORMAL - normal Font for writing text like Arial, Verdana, Arial Narrow, Trebuchet, Times, Courier, ...
+// IMPL_FONT_ATTR_SYMBOL - Font with symbols
+// IMPL_FONT_ATTR_DECORATIVE - Readable and normally used for drawings
+// IMPL_FONT_ATTR_SPECIAL - very special design
+// IMPL_FONT_ATTR_TITLING - only uppercase characters
+// IMPL_FONT_ATTR_FULL - Font with normally all characters
+// IMPL_FONT_ATTR_CAPITALS - only uppercase characters, but lowercase characters smaller as the uppercase characters
+// IMPL_FONT_ATTR_TYPEWRITER - like a typewriter: Courier, ...
+// IMPL_FONT_ATTR_SCRIPT - Handwriting or Script
+// IMPL_FONT_ATTR_HANDWRITING - More Handwriting with normal letters
+// IMPL_FONT_ATTR_CHANCERY - Like Zapf Chancery
+// IMPL_FONT_ATTR_COMIC - Like Comic Sans MS
+// IMPL_FONT_ATTR_BRUSHSCRIPT - More Script
+// IMPL_FONT_ATTR_OTHERSTYLE - OldStyle, ... so negativ points
+#define IMPL_FONT_ATTR_DEFAULT ((ULONG)0x00000001)
+#define IMPL_FONT_ATTR_STANDARD ((ULONG)0x00000002)
+#define IMPL_FONT_ATTR_NORMAL ((ULONG)0x00000004)
+#define IMPL_FONT_ATTR_SYMBOL ((ULONG)0x00000008)
+#define IMPL_FONT_ATTR_FIXED ((ULONG)0x00000010)
+#define IMPL_FONT_ATTR_SANSSERIF ((ULONG)0x00000020)
+#define IMPL_FONT_ATTR_SERIF ((ULONG)0x00000040)
+#define IMPL_FONT_ATTR_DECORATIVE ((ULONG)0x00000080)
+#define IMPL_FONT_ATTR_SPECIAL ((ULONG)0x00000100)
+#define IMPL_FONT_ATTR_ITALIC ((ULONG)0x00000200)
+#define IMPL_FONT_ATTR_TITLING ((ULONG)0x00000400)
+#define IMPL_FONT_ATTR_CAPITALS ((ULONG)0x00000800)
+#define IMPL_FONT_ATTR_CJK ((ULONG)0x00001000)
+#define IMPL_FONT_ATTR_CJK_JP ((ULONG)0x00002000)
+#define IMPL_FONT_ATTR_CJK_SC ((ULONG)0x00004000)
+#define IMPL_FONT_ATTR_CJK_TC ((ULONG)0x00008000)
+#define IMPL_FONT_ATTR_CJK_KR ((ULONG)0x00010000)
+#define IMPL_FONT_ATTR_CTL ((ULONG)0x00020000)
+#define IMPL_FONT_ATTR_NONELATIN ((ULONG)0x00040000)
+#define IMPL_FONT_ATTR_FULL ((ULONG)0x00080000)
+#define IMPL_FONT_ATTR_OUTLINE ((ULONG)0x00100000)
+#define IMPL_FONT_ATTR_SHADOW ((ULONG)0x00200000)
+#define IMPL_FONT_ATTR_ROUNDED ((ULONG)0x00400000)
+#define IMPL_FONT_ATTR_TYPEWRITER ((ULONG)0x00800000)
+#define IMPL_FONT_ATTR_SCRIPT ((ULONG)0x01000000)
+#define IMPL_FONT_ATTR_HANDWRITING ((ULONG)0x02000000)
+#define IMPL_FONT_ATTR_CHANCERY ((ULONG)0x04000000)
+#define IMPL_FONT_ATTR_COMIC ((ULONG)0x08000000)
+#define IMPL_FONT_ATTR_BRUSHSCRIPT ((ULONG)0x10000000)
+#define IMPL_FONT_ATTR_GOTHIC ((ULONG)0x20000000)
+#define IMPL_FONT_ATTR_SCHOOLBOOK ((ULONG)0x40000000)
+#define IMPL_FONT_ATTR_OTHERSTYLE ((ULONG)0x80000000)
+
+#define IMPL_FONT_ATTR_CJK_ALLLANG (IMPL_FONT_ATTR_CJK_JP | IMPL_FONT_ATTR_CJK_SC | IMPL_FONT_ATTR_CJK_TC | IMPL_FONT_ATTR_CJK_KR)
+#define IMPL_FONT_ATTR_ALLSCRIPT (IMPL_FONT_ATTR_SCRIPT | IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_COMIC | IMPL_FONT_ATTR_BRUSHSCRIPT)
+#define IMPL_FONT_ATTR_ALLSUBSCRIPT (IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_COMIC | IMPL_FONT_ATTR_BRUSHSCRIPT)
+#define IMPL_FONT_ATTR_ALLSERIFSTYLE (IMPL_FONT_ATTR_ALLSCRIPT |\
+ IMPL_FONT_ATTR_SANSSERIF | IMPL_FONT_ATTR_SERIF |\
+ IMPL_FONT_ATTR_FIXED | IMPL_FONT_ATTR_ITALIC |\
+ IMPL_FONT_ATTR_GOTHIC | IMPL_FONT_ATTR_SCHOOLBOOK |\
+ IMPL_FONT_ATTR_SHADOW | IMPL_FONT_ATTR_OUTLINE)
+
+struct UNOTOOLS_DLLPUBLIC FontNameAttr
+{
+ String Name;
+ ::std::vector< String > Substitutions;
+ ::std::vector< String > MSSubstitutions;
+ ::std::vector< String > PSSubstitutions;
+ ::std::vector< String > HTMLSubstitutions;
+ FontWeight Weight;
+ FontWidth Width;
+ unsigned long Type; // bitfield of IMPL_FONT_ATTR_*
+};
+
+class UNOTOOLS_DLLPUBLIC FontSubstConfiguration
+{
+private:
+ com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >
+ m_xConfigProvider;
+ com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >
+ m_xConfigAccess;
+ struct LocaleSubst
+ {
+ rtl::OUString aConfigLocaleString;
+ mutable bool bConfigRead;
+ // note: aSubstAttributes must be sorted alphabetically by Name
+ // searches on the substitutes are done with Name as key, where
+ // a minimal match is sufficient (that is e.g. "Thorndale" will match
+ // "Thorndale BlaBlub"). Also names must be lower case.
+ mutable std::vector< FontNameAttr > aSubstAttributes;
+
+ LocaleSubst() : bConfigRead( false ) {}
+ };
+ std::hash_map< com::sun::star::lang::Locale, LocaleSubst, utl::LocaleHash > m_aSubst;
+ typedef std::hash_set< rtl::OUString, rtl::OUStringHash > UniqueSubstHash;
+ mutable UniqueSubstHash maSubstHash;
+
+
+ void fillSubstVector( const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xFont,
+ const rtl::OUString& rType,
+ std::vector< String >& rSubstVector ) const;
+ FontWeight getSubstWeight( const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xFont,
+ const rtl::OUString& rType ) const;
+ FontWidth getSubstWidth( const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xFont,
+ const rtl::OUString& rType ) const;
+ unsigned long getSubstType( const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess > xFont,
+ const rtl::OUString& rType ) const;
+ void readLocaleSubst( const com::sun::star::lang::Locale& rLocale ) const;
+ FontSubstConfiguration();
+public:
+ ~FontSubstConfiguration();
+
+ static FontSubstConfiguration* get();
+
+ const FontNameAttr* getSubstInfo(
+ const String& rFontName,
+ const com::sun::star::lang::Locale& rLocale =
+ com::sun::star::lang::Locale( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ),
+ rtl::OUString(),
+ rtl::OUString() )
+ ) const;
+ static void getMapName( const String& rOrgName, String& rShortName, String& rFamilyName, FontWeight& rWeight, FontWidth& rWidth, ULONG& rType );
+};
+
+} // namespace utl
+
+#endif // _UNOTOOLS_FONTCFG_HXX
diff --git a/unotools/inc/unotools/fontcvt.hxx b/unotools/inc/unotools/fontcvt.hxx
new file mode 100644
index 000000000000..679a2dc5a6d9
--- /dev/null
+++ b/unotools/inc/unotools/fontcvt.hxx
@@ -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: fontcvt.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 _UNOTOOLS_FONTCVT_HXX
+#define _UNOTOOLS_FONTCVT_HXX
+
+#include <unotools/unotoolsdllapi.h>
+#include <tools/string.hxx>
+
+// ------------------
+// - FontToSubsFont -
+// ------------------
+
+#define FONTTOSUBSFONT_IMPORT ((ULONG)0x00000001)
+#define FONTTOSUBSFONT_EXPORT ((ULONG)0x00000002)
+#define FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS ((ULONG)0x00000004)
+
+typedef void* FontToSubsFontConverter;
+UNOTOOLS_DLLPUBLIC FontToSubsFontConverter CreateFontToSubsFontConverter( const String& rFontName, ULONG nFlags );
+UNOTOOLS_DLLPUBLIC void DestroyFontToSubsFontConverter( FontToSubsFontConverter hConverter );
+UNOTOOLS_DLLPUBLIC sal_Unicode ConvertFontToSubsFontChar( FontToSubsFontConverter hConverter, sal_Unicode c );
+UNOTOOLS_DLLPUBLIC String GetFontToSubsFontName( FontToSubsFontConverter hConverter );
+
+// ---------------------------
+// - StarSymbolToMSMultiFont -
+// ---------------------------
+
+class UNOTOOLS_DLLPUBLIC StarSymbolToMSMultiFont
+{
+public:
+ //Returns the name of the best windows symbol font which this char can be
+ //mapped to. Sets rChar to the correct position for that font. If no
+ //match found, then no name is returned, and rChar is unchanged. If you
+ //want to convert a string, you don't want to use this.
+ virtual String ConvertChar(sal_Unicode &rChar) = 0;
+
+ //Starts converting the string at position rIndex. It converts as much of
+ //the string that can be converted to the same symbol font and returns the
+ //name of that font. rIndex is modified to the last index that was
+ //converted. Typically you call if continously until rIndex ==
+ //rString.Len() and handle each section as seperate 8bit strings using
+ //seperate fonts. Will return an empty string for a continous section
+ //that has no possible mapping.
+ virtual String ConvertString(String &rString, xub_StrLen &rIndex) = 0;
+ virtual ~StarSymbolToMSMultiFont() {}
+};
+
+//with bPerfect set the converter will only try and convert symbols which have
+//perfect mappings to the windows symbols fonts. With it not set, it will
+//allow somewhat more dubious transformations that are nevertheless
+//recognizably similiar. Even in this mode there will be characters that fail.
+//The users of this might want to make a distinction between failed characters
+//which were inside and those outside the unicode private area.
+UNOTOOLS_DLLPUBLIC StarSymbolToMSMultiFont *CreateStarSymbolToMSMultiFont(bool bPerfectOnly=false);
+#endif // _UNOTOOLS_FONTCVT_HXX
diff --git a/unotools/inc/unotools/fontdefs.hxx b/unotools/inc/unotools/fontdefs.hxx
new file mode 100644
index 000000000000..e595fe45400d
--- /dev/null
+++ b/unotools/inc/unotools/fontdefs.hxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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 _UNOTOOLS_FONTDEFS_HXX
+#define _UNOTOOLS_FONTDEFS_HXX
+
+#include <unotools/unotoolsdllapi.h>
+#include <sal/types.h>
+#include <tools/string.hxx>
+
+namespace utl {
+ class FontSubstConfiguration;
+ class FontNameAttr;
+}
+
+// ----------------
+// - SubsFontName -
+// ----------------
+
+#define SUBSFONT_ONLYONE ((ULONG)0x00000001)
+#define SUBSFONT_MS ((ULONG)0x00000002)
+#define SUBSFONT_PS ((ULONG)0x00000004)
+#define SUBSFONT_HTML ((ULONG)0x00000008)
+
+UNOTOOLS_DLLPUBLIC String GetSubsFontName( const String& rName, ULONG nFlags );
+
+// -----------------
+// - FontTokenName -
+// -----------------
+
+UNOTOOLS_DLLPUBLIC String GetFontToken( const String& rName, xub_StrLen nToken, xub_StrLen& rIndex );
+inline String GetFontToken( const String& rName, xub_StrLen nToken )
+{
+ xub_StrLen nTempIndex = 0;
+ return GetFontToken( rName, nToken, nTempIndex );
+}
+
+UNOTOOLS_DLLPUBLIC void AddTokenFontName( String& rName, const String& rNewToken );
+
+struct UNOTOOLS_DLLPUBLIC FontNameHash { int operator()(const String&) const; };
+
+// ---------------
+// - ConvertChar -
+// ---------------
+
+class UNOTOOLS_DLLPUBLIC ConvertChar
+{
+public:
+ const sal_Unicode* mpCvtTab;
+ const char* mpSubsFontName;
+ sal_Unicode (*mpCvtFunc)( sal_Unicode );
+ sal_Unicode RecodeChar( sal_Unicode c ) const;
+ void RecodeString( String& rStra, xub_StrLen nIndex, xub_StrLen nLen ) const;
+ static const ConvertChar* GetRecodeData( const String& rOrgFontName, const String& rMapFontName );
+};
+
+
+// Default-Font
+#define DEFAULTFONT_SANS_UNICODE ((USHORT)1)
+#define DEFAULTFONT_SANS ((USHORT)2)
+#define DEFAULTFONT_SERIF ((USHORT)3)
+#define DEFAULTFONT_FIXED ((USHORT)4)
+#define DEFAULTFONT_SYMBOL ((USHORT)5)
+#define DEFAULTFONT_UI_SANS ((USHORT)1000)
+#define DEFAULTFONT_UI_FIXED ((USHORT)1001)
+#define DEFAULTFONT_LATIN_TEXT ((USHORT)2000)
+#define DEFAULTFONT_LATIN_PRESENTATION ((USHORT)2001)
+#define DEFAULTFONT_LATIN_SPREADSHEET ((USHORT)2002)
+#define DEFAULTFONT_LATIN_HEADING ((USHORT)2003)
+#define DEFAULTFONT_LATIN_DISPLAY ((USHORT)2004)
+#define DEFAULTFONT_LATIN_FIXED ((USHORT)2005)
+#define DEFAULTFONT_CJK_TEXT ((USHORT)3000)
+#define DEFAULTFONT_CJK_PRESENTATION ((USHORT)3001)
+#define DEFAULTFONT_CJK_SPREADSHEET ((USHORT)3002)
+#define DEFAULTFONT_CJK_HEADING ((USHORT)3003)
+#define DEFAULTFONT_CJK_DISPLAY ((USHORT)3004)
+#define DEFAULTFONT_CTL_TEXT ((USHORT)4000)
+#define DEFAULTFONT_CTL_PRESENTATION ((USHORT)4001)
+#define DEFAULTFONT_CTL_SPREADSHEET ((USHORT)4002)
+#define DEFAULTFONT_CTL_HEADING ((USHORT)4003)
+#define DEFAULTFONT_CTL_DISPLAY ((USHORT)4004)
+
+UNOTOOLS_DLLPUBLIC String GetNextFontToken( const String& rTokenStr, xub_StrLen& rIndex );
+
+UNOTOOLS_DLLPUBLIC void GetEnglishSearchFontName( String& rName );
+
+#endif
diff --git a/unotools/source/config/fontcfg.cxx b/unotools/source/config/fontcfg.cxx
new file mode 100644
index 000000000000..3ee556f372c7
--- /dev/null
+++ b/unotools/source/config/fontcfg.cxx
@@ -0,0 +1,1220 @@
+/*************************************************************************
+ *
+ * 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: fontcfg.cxx,v $
+ * $Revision: 1.49.114.1 $
+ *
+ * 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_unotools.hxx"
+#include <unotools/fontcfg.hxx>
+#include <unotools/fontdefs.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <unotools/configpathes.hxx>
+#include <unotools/syslocale.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/debug.hxx>
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+#include <string.h>
+#include <list>
+#include <algorithm>
+
+#define DEFAULTFONT_CONFIGNODE "VCL/DefaultFonts"
+#define SUBSTFONT_CONFIGNODE "VCL/FontSubstitutions"
+
+using namespace rtl;
+using namespace utl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+
+static DefaultFontConfiguration* mpDefaultFontConfiguration = 0;
+
+static FontSubstConfiguration* mpFontSubstConfiguration = 0;
+
+/*
+ * DefaultFontConfiguration
+ */
+
+static const char* getKeyType( int nKeyType )
+{
+ switch( nKeyType )
+ {
+ case DEFAULTFONT_CJK_DISPLAY: return "CJK_DISPLAY";
+ case DEFAULTFONT_CJK_HEADING: return "CJK_HEADING";
+ case DEFAULTFONT_CJK_PRESENTATION: return "CJK_PRESENTATION";
+ case DEFAULTFONT_CJK_SPREADSHEET: return "CJK_SPREADSHEET";
+ case DEFAULTFONT_CJK_TEXT: return "CJK_TEXT";
+ case DEFAULTFONT_CTL_DISPLAY: return "CTL_DISPLAY";
+ case DEFAULTFONT_CTL_HEADING: return "CTL_HEADING";
+ case DEFAULTFONT_CTL_PRESENTATION: return "CTL_PRESENTATION";
+ case DEFAULTFONT_CTL_SPREADSHEET: return "CTL_SPREADSHEET";
+ case DEFAULTFONT_CTL_TEXT: return "CTL_TEXT";
+ case DEFAULTFONT_FIXED: return "FIXED";
+ case DEFAULTFONT_LATIN_DISPLAY: return "LATIN_DISPLAY";
+ case DEFAULTFONT_LATIN_FIXED: return "LATIN_FIXED";
+ case DEFAULTFONT_LATIN_HEADING: return "LATIN_HEADING";
+ case DEFAULTFONT_LATIN_PRESENTATION: return "LATIN_PRESENTATION";
+ case DEFAULTFONT_LATIN_SPREADSHEET: return "LATIN_SPREADSHEET";
+ case DEFAULTFONT_LATIN_TEXT: return "LATIN_TEXT";
+ case DEFAULTFONT_SANS: return "SANS";
+ case DEFAULTFONT_SANS_UNICODE: return "SANS_UNICODE";
+ case DEFAULTFONT_SERIF: return "SERIF";
+ case DEFAULTFONT_SYMBOL: return "SYMBOL";
+ case DEFAULTFONT_UI_FIXED: return "UI_FIXED";
+ case DEFAULTFONT_UI_SANS: return "UI_SANS";
+ default:
+ DBG_ERROR( "unmatched type" );
+ return "";
+ }
+}
+
+DefaultFontConfiguration* DefaultFontConfiguration::get()
+{
+ if( !mpDefaultFontConfiguration )
+ mpDefaultFontConfiguration = new DefaultFontConfiguration();
+ return mpDefaultFontConfiguration;
+}
+
+DefaultFontConfiguration::DefaultFontConfiguration()
+{
+ try
+ {
+ // get service provider
+ Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() );
+ // create configuration hierachical access name
+ if( xSMgr.is() )
+ {
+ try
+ {
+ m_xConfigProvider =
+ Reference< XMultiServiceFactory >(
+ xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider" ))),
+ UNO_QUERY );
+ if( m_xConfigProvider.is() )
+ {
+ Sequence< Any > aArgs(1);
+ PropertyValue aVal;
+ aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.VCL/DefaultFonts" ) );
+ aArgs.getArray()[0] <<= aVal;
+ m_xConfigAccess =
+ Reference< XNameAccess >(
+ m_xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" )),
+ aArgs ),
+ UNO_QUERY );
+ if( m_xConfigAccess.is() )
+ {
+ Sequence< OUString > aLocales = m_xConfigAccess->getElementNames();
+ // fill config hash with empty interfaces
+ int nLocales = aLocales.getLength();
+ const OUString* pLocaleStrings = aLocales.getConstArray();
+ Locale aLoc;
+ for( int i = 0; i < nLocales; i++ )
+ {
+ sal_Int32 nIndex = 0;
+ aLoc.Language = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiLowerCase();
+ if( nIndex != -1 )
+ aLoc.Country = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase();
+ else
+ aLoc.Country = OUString();
+ if( nIndex != -1 )
+ aLoc.Variant = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase();
+ else
+ aLoc.Variant = OUString();
+ m_aConfig[ aLoc ] = LocaleAccess();
+ m_aConfig[ aLoc ].aConfigLocaleString = pLocaleStrings[i];
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ // configuration is awry
+ m_xConfigProvider.clear();
+ m_xConfigAccess.clear();
+ }
+ }
+ }
+ catch( WrappedTargetException& )
+ {
+ }
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "config provider: %s, config access: %s\n",
+ m_xConfigProvider.is() ? "true" : "false",
+ m_xConfigAccess.is() ? "true" : "false"
+ );
+ #endif
+}
+
+DefaultFontConfiguration::~DefaultFontConfiguration()
+{
+ // release all nodes
+ m_aConfig.clear();
+ // release top node
+ m_xConfigAccess.clear();
+ // release config provider
+ m_xConfigProvider.clear();
+}
+
+OUString DefaultFontConfiguration::tryLocale( const Locale& rLocale, const OUString& rType ) const
+{
+ OUString aRet;
+
+ std::hash_map< Locale, LocaleAccess, LocaleHash >::const_iterator it =
+ m_aConfig.find( rLocale );
+ if( it != m_aConfig.end() )
+ {
+ if( !it->second.xAccess.is() )
+ {
+ try
+ {
+ Reference< XNameAccess > xNode;
+ if ( m_xConfigAccess->hasByName( it->second.aConfigLocaleString ) )
+ {
+ Any aAny = m_xConfigAccess->getByName( it->second.aConfigLocaleString );
+ if( aAny >>= xNode )
+ it->second.xAccess = xNode;
+ }
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+ }
+ if( it->second.xAccess.is() )
+ {
+ try
+ {
+ if ( it->second.xAccess->hasByName( rType ) )
+ {
+ Any aAny = it->second.xAccess->getByName( rType );
+ aAny >>= aRet;
+ }
+ }
+ catch( NoSuchElementException& )
+ {
+ }
+ catch( WrappedTargetException& )
+ {
+ }
+ }
+ }
+
+ return aRet;
+}
+
+OUString DefaultFontConfiguration::getDefaultFont( const Locale& rLocale, int nType ) const
+{
+ Locale aLocale;
+ aLocale.Language = rLocale.Language.toAsciiLowerCase();
+ aLocale.Country = rLocale.Country.toAsciiUpperCase();
+ aLocale.Variant = rLocale.Variant.toAsciiUpperCase();
+
+ OUString aType = OUString::createFromAscii( getKeyType( nType ) );
+ OUString aRet = tryLocale( aLocale, aType );
+ if( ! aRet.getLength() && aLocale.Variant.getLength() )
+ {
+ aLocale.Variant = OUString();
+ aRet = tryLocale( aLocale, aType );
+ }
+ if( ! aRet.getLength() && aLocale.Country.getLength() )
+ {
+ aLocale.Country = OUString();
+ aRet = tryLocale( aLocale, aType );
+ }
+ if( ! aRet.getLength() )
+ {
+ aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) );
+ aRet = tryLocale( aLocale, aType );
+ }
+ return aRet;
+}
+
+OUString DefaultFontConfiguration::getUserInterfaceFont( const Locale& rLocale ) const
+{
+ Locale aLocale = rLocale;
+ if( ! aLocale.Language.getLength() )
+ aLocale = SvtSysLocale().GetUILocale();
+
+ OUString aUIFont = getDefaultFont( aLocale, DEFAULTFONT_UI_SANS );
+
+ if( aUIFont.getLength() )
+ return aUIFont;
+
+ // fallback mechanism (either no configuration or no entry in configuration
+
+ #define FALLBACKFONT_UI_SANS "Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Bitstream Vera Sans;gnu-unifont;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System"
+ #define FALLBACKFONT_UI_SANS_LATIN2 "Andale Sans UI;Albany;Albany AMT;Tahoma;Arial Unicode MS;Arial;Nimbus Sans L;Luxi Sans;Bitstream Vera Sans;Interface User;Geneva;WarpSans;Dialog;Swiss;Lucida;Helvetica;Charcoal;Chicago;MS Sans Serif;Helv;Times;Times New Roman;Interface System"
+ #define FALLBACKFONT_UI_SANS_ARABIC "Tahoma;Traditional Arabic;Simplified Arabic;Lucidasans;Lucida Sans;Supplement;Andale Sans UI;clearlyU;Interface User;Arial Unicode MS;Lucida Sans Unicode;WarpSans;Geneva;MS Sans Serif;Helv;Dialog;Albany;Lucida;Helvetica;Charcoal;Chicago;Arial;Helmet;Interface System;Sans Serif"
+ #define FALLBACKFONT_UI_SANS_THAI "OONaksit;Tahoma;Lucidasans;Arial Unicode MS"
+ #define FALLBACKFONT_UI_SANS_KOREAN "SunGulim;BaekmukGulim;Gulim;Roundgothic;Arial Unicode MS;Lucida Sans Unicode;gnu-unifont;Andale Sans UI"
+ #define FALLBACKFONT_UI_SANS_JAPANESE1 "HG-GothicB-Sun;Andale Sans UI;HG MhinchoLightJ"
+ #define FALLBACKFONT_UI_SANS_JAPANESE2 "Kochi Gothic;Gothic"
+ #define FALLBACKFONT_UI_SANS_CHINSIM "Andale Sans UI;Arial Unicode MS;ZYSong18030;AR PL SungtiL GB;AR PL KaitiM GB;SimSun;Lucida Sans Unicode;Fangsong;Hei;Song;Kai;Ming;gnu-unifont;Interface User;"
+ #define FALLBACKFONT_UI_SANS_CHINTRD "Andale Sans UI;Arial Unicode MS;AR PL Mingti2L Big5;AR PL KaitiM Big5;Kai;PMingLiU;MingLiU;Ming;Lucida Sans Unicode;gnu-unifont;Interface User;"
+
+ // we need localized names for japanese fonts
+ static sal_Unicode const aMSGothic[] = { 0xFF2D, 0xFF33, ' ', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+ static sal_Unicode const aMSPGothic[] = { 0xFF2D, 0xFF33, ' ', 0xFF30, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+ static sal_Unicode const aTLPGothic[] = { 0x0054, 0x004C, 0x0050, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+ static sal_Unicode const aLXGothic[] = { 0x004C, 0x0058, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+ static sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+
+ String aFallBackJapaneseLocalized( RTL_CONSTASCII_USTRINGPARAM( "MS UI Gothic;" ) );
+ aFallBackJapaneseLocalized += String( RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_JAPANESE1 ) );
+ aFallBackJapaneseLocalized += String( aMSPGothic );
+ aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackJapaneseLocalized += String( aMSGothic );
+ aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackJapaneseLocalized += String( aTLPGothic );
+ aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackJapaneseLocalized += String( aLXGothic );
+ aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackJapaneseLocalized += String( aKochiGothic );
+ aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackJapaneseLocalized += String(RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_JAPANESE2 ) );
+ static const OUString aFallBackJapanese( aFallBackJapaneseLocalized );
+ static const OUString aFallback (RTL_CONSTASCII_USTRINGPARAM(FALLBACKFONT_UI_SANS));
+ static const OUString aFallbackLatin2 (RTL_CONSTASCII_USTRINGPARAM(FALLBACKFONT_UI_SANS_LATIN2));
+ static const OUString aFallBackArabic (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_ARABIC ) );
+ static const OUString aFallBackThai (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_THAI ) );
+ static const OUString aFallBackChineseSIM (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_CHINSIM ) );
+ static const OUString aFallBackChineseTRD (RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_CHINTRD ) );
+
+ // we need localized names for korean fonts
+ static sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0 };
+ static sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBC35, 0xAD74, 0xB9BC, 0 };
+ String aFallBackKoreanLocalized( aSunGulim );
+ aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackKoreanLocalized += String( aBaekmukGulim );
+ aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( ";" ) );
+ aFallBackKoreanLocalized += String(RTL_CONSTASCII_USTRINGPARAM( FALLBACKFONT_UI_SANS_KOREAN ) );
+ static const OUString aFallBackKorean( aFallBackKoreanLocalized );
+
+ // optimize font list for some locales, as long as Andale Sans UI does not support them
+ if( aLocale.Language.equalsAscii( "ar" ) ||
+ aLocale.Language.equalsAscii( "he" ) ||
+ aLocale.Language.equalsAscii( "iw" ) )
+ {
+ return aFallBackArabic;
+ }
+ else if( aLocale.Language.equalsAscii( "th" ) )
+ {
+ return aFallBackThai;
+ }
+ else if( aLocale.Language.equalsAscii( "ko" ) )
+ {
+ return aFallBackKorean;
+ }
+ else if( aLocale.Language.equalsAscii( "cs" ) ||
+ aLocale.Language.equalsAscii( "hu" ) ||
+ aLocale.Language.equalsAscii( "pl" ) ||
+ aLocale.Language.equalsAscii( "ro" ) ||
+ aLocale.Language.equalsAscii( "rm" ) ||
+ aLocale.Language.equalsAscii( "hr" ) ||
+ aLocale.Language.equalsAscii( "sk" ) ||
+ aLocale.Language.equalsAscii( "sl" ) ||
+ aLocale.Language.equalsAscii( "sb" ) )
+ {
+ return aFallbackLatin2;
+ }
+ else if( aLocale.Language.equalsAscii( "zh" ) )
+ {
+ if( ! aLocale.Country.equalsAscii( "cn" ) )
+ return aFallBackChineseTRD;
+ else
+ return aFallBackChineseSIM;
+ }
+ else if( aLocale.Language.equalsAscii( "ja" ) )
+ {
+ return aFallBackJapanese;
+ }
+
+ return aFallback;
+}
+
+// ------------------------------------------------------------------------------------
+
+/*
+ * FontSubstConfigItem::get
+ */
+
+FontSubstConfiguration* FontSubstConfiguration::get()
+{
+ if( !mpFontSubstConfiguration )
+ mpFontSubstConfiguration = new FontSubstConfiguration();
+ return mpFontSubstConfiguration;
+}
+
+/*
+ * FontSubstConfigItem::FontSubstConfigItem
+ */
+
+FontSubstConfiguration::FontSubstConfiguration() :
+ maSubstHash( 300 )
+{
+ try
+ {
+ // get service provider
+ Reference< XMultiServiceFactory > xSMgr( comphelper::getProcessServiceFactory() );
+ // create configuration hierachical access name
+ if( xSMgr.is() )
+ {
+ try
+ {
+ m_xConfigProvider =
+ Reference< XMultiServiceFactory >(
+ xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider" ))),
+ UNO_QUERY );
+ if( m_xConfigProvider.is() )
+ {
+ Sequence< Any > aArgs(1);
+ PropertyValue aVal;
+ aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
+ aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.VCL/FontSubstitutions" ) );
+ aArgs.getArray()[0] <<= aVal;
+ m_xConfigAccess =
+ Reference< XNameAccess >(
+ m_xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess" )),
+ aArgs ),
+ UNO_QUERY );
+ if( m_xConfigAccess.is() )
+ {
+ Sequence< OUString > aLocales = m_xConfigAccess->getElementNames();
+ // fill config hash with empty interfaces
+ int nLocales = aLocales.getLength();
+ const OUString* pLocaleStrings = aLocales.getConstArray();
+ Locale aLoc;
+ for( int i = 0; i < nLocales; i++ )
+ {
+ sal_Int32 nIndex = 0;
+ aLoc.Language = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiLowerCase();
+ if( nIndex != -1 )
+ aLoc.Country = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase();
+ else
+ aLoc.Country = OUString();
+ if( nIndex != -1 )
+ aLoc.Variant = pLocaleStrings[i].getToken( 0, sal_Unicode('-'), nIndex ).toAsciiUpperCase();
+ else
+ aLoc.Variant = OUString();
+ m_aSubst[ aLoc ] = LocaleSubst();
+ m_aSubst[ aLoc ].aConfigLocaleString = pLocaleStrings[i];
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ // configuration is awry
+ m_xConfigProvider.clear();
+ m_xConfigAccess.clear();
+ }
+ }
+ }
+ catch( WrappedTargetException& )
+ {
+ }
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "config provider: %s, config access: %s\n",
+ m_xConfigProvider.is() ? "true" : "false",
+ m_xConfigAccess.is() ? "true" : "false"
+ );
+ #endif
+}
+
+/*
+ * FontSubstConfigItem::~FontSubstConfigItem
+ */
+
+FontSubstConfiguration::~FontSubstConfiguration()
+{
+ // release config access
+ m_xConfigAccess.clear();
+ // release config provider
+ m_xConfigProvider.clear();
+}
+
+/*
+ * FontSubstConfigItem::getMapName
+ */
+// =======================================================================
+
+static const char* const aImplKillLeadingList[] =
+{
+ "microsoft",
+ "monotype",
+ "linotype",
+ "baekmuk",
+ "adobe",
+ "nimbus",
+ "zycjk",
+ "itc",
+ "sun",
+ "amt",
+ "ms",
+ "mt",
+ "cg",
+ "hg",
+ "fz",
+ "ipa",
+ "sazanami",
+ "kochi",
+ NULL
+};
+
+// -----------------------------------------------------------------------
+
+static const char* const aImplKillTrailingList[] =
+{
+ "microsoft",
+ "monotype",
+ "linotype",
+ "adobe",
+ "nimbus",
+ "itc",
+ "sun",
+ "amt",
+ "ms",
+ "mt",
+ "clm",
+ // Scripts, for compatibility with older versions
+ "we",
+ "cyr",
+ "tur",
+ "wt",
+ "greek",
+ "wl",
+ // CJK extensions
+ "gb",
+ "big5",
+ "pro",
+ "z01",
+ "z02",
+ "z03",
+ "z13",
+ "b01",
+ "w3x12",
+ // Old Printer Fontnames
+ "5cpi",
+ "6cpi",
+ "7cpi",
+ "8cpi",
+ "9cpi",
+ "10cpi",
+ "11cpi",
+ "12cpi",
+ "13cpi",
+ "14cpi",
+ "15cpi",
+ "16cpi",
+ "18cpi",
+ "24cpi",
+ "scale",
+ "pc",
+ NULL
+};
+
+// -----------------------------------------------------------------------
+
+static const char* const aImplKillTrailingWithExceptionsList[] =
+{
+ "ce", "monospace", "oldface", NULL,
+ "ps", "caps", NULL,
+ NULL
+};
+
+// -----------------------------------------------------------------------
+
+struct ImplFontAttrWeightSearchData
+{
+ const char* mpStr;
+ FontWeight meWeight;
+};
+
+static ImplFontAttrWeightSearchData const aImplWeightAttrSearchList[] =
+{
+// the attribute names are ordered by "first match wins"
+// e.g. "semilight" should wins over "semi"
+{ "extrablack", WEIGHT_BLACK },
+{ "ultrablack", WEIGHT_BLACK },
+{ "ultrabold", WEIGHT_ULTRABOLD },
+{ "semibold", WEIGHT_SEMIBOLD },
+{ "semilight", WEIGHT_SEMILIGHT },
+{ "semi", WEIGHT_SEMIBOLD },
+{ "demi", WEIGHT_SEMIBOLD },
+{ "black", WEIGHT_BLACK },
+{ "bold", WEIGHT_BOLD },
+{ "heavy", WEIGHT_BLACK },
+{ "ultralight", WEIGHT_ULTRALIGHT },
+{ "light", WEIGHT_LIGHT },
+{ "medium", WEIGHT_MEDIUM },
+{ NULL, WEIGHT_DONTKNOW },
+};
+
+// -----------------------------------------------------------------------
+
+struct ImplFontAttrWidthSearchData
+{
+ const char* mpStr;
+ FontWidth meWidth;
+};
+
+static ImplFontAttrWidthSearchData const aImplWidthAttrSearchList[] =
+{
+{ "narrow", WIDTH_CONDENSED },
+{ "semicondensed", WIDTH_SEMI_CONDENSED },
+{ "ultracondensed", WIDTH_ULTRA_CONDENSED },
+{ "semiexpanded", WIDTH_SEMI_EXPANDED },
+{ "ultraexpanded", WIDTH_ULTRA_EXPANDED },
+{ "expanded", WIDTH_EXPANDED },
+{ "wide", WIDTH_ULTRA_EXPANDED },
+{ "condensed", WIDTH_CONDENSED },
+{ "cond", WIDTH_CONDENSED },
+{ "cn", WIDTH_CONDENSED },
+{ NULL, WIDTH_DONTKNOW },
+};
+
+struct ImplFontAttrTypeSearchData
+{
+ const char* mpStr;
+ ULONG mnType;
+};
+
+static ImplFontAttrTypeSearchData const aImplTypeAttrSearchList[] =
+{
+{ "monotype", 0 },
+{ "linotype", 0 },
+{ "titling", IMPL_FONT_ATTR_TITLING },
+{ "captitals", IMPL_FONT_ATTR_CAPITALS },
+{ "captital", IMPL_FONT_ATTR_CAPITALS },
+{ "caps", IMPL_FONT_ATTR_CAPITALS },
+{ "italic", IMPL_FONT_ATTR_ITALIC },
+{ "oblique", IMPL_FONT_ATTR_ITALIC },
+{ "rounded", IMPL_FONT_ATTR_ROUNDED },
+{ "outline", IMPL_FONT_ATTR_OUTLINE },
+{ "shadow", IMPL_FONT_ATTR_SHADOW },
+{ "handwriting", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT },
+{ "hand", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT },
+{ "signet", IMPL_FONT_ATTR_HANDWRITING | IMPL_FONT_ATTR_SCRIPT },
+{ "script", IMPL_FONT_ATTR_BRUSHSCRIPT | IMPL_FONT_ATTR_SCRIPT },
+{ "calligraphy", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT },
+{ "chancery", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT },
+{ "corsiva", IMPL_FONT_ATTR_CHANCERY | IMPL_FONT_ATTR_SCRIPT },
+{ "gothic", IMPL_FONT_ATTR_SANSSERIF | IMPL_FONT_ATTR_GOTHIC },
+{ "schoolbook", IMPL_FONT_ATTR_SERIF | IMPL_FONT_ATTR_SCHOOLBOOK },
+{ "schlbk", IMPL_FONT_ATTR_SERIF | IMPL_FONT_ATTR_SCHOOLBOOK },
+{ "typewriter", IMPL_FONT_ATTR_TYPEWRITER | IMPL_FONT_ATTR_FIXED },
+{ "lineprinter", IMPL_FONT_ATTR_TYPEWRITER | IMPL_FONT_ATTR_FIXED },
+{ "monospaced", IMPL_FONT_ATTR_FIXED },
+{ "monospace", IMPL_FONT_ATTR_FIXED },
+{ "mono", IMPL_FONT_ATTR_FIXED },
+{ "fixed", IMPL_FONT_ATTR_FIXED },
+{ "sansserif", IMPL_FONT_ATTR_SANSSERIF },
+{ "sans", IMPL_FONT_ATTR_SANSSERIF },
+{ "swiss", IMPL_FONT_ATTR_SANSSERIF },
+{ "serif", IMPL_FONT_ATTR_SERIF },
+{ "bright", IMPL_FONT_ATTR_SERIF },
+{ "symbols", IMPL_FONT_ATTR_SYMBOL },
+{ "symbol", IMPL_FONT_ATTR_SYMBOL },
+{ "dingbats", IMPL_FONT_ATTR_SYMBOL },
+{ "dings", IMPL_FONT_ATTR_SYMBOL },
+{ "ding", IMPL_FONT_ATTR_SYMBOL },
+{ "bats", IMPL_FONT_ATTR_SYMBOL },
+{ "math", IMPL_FONT_ATTR_SYMBOL },
+{ "oldstyle", IMPL_FONT_ATTR_OTHERSTYLE },
+{ "oldface", IMPL_FONT_ATTR_OTHERSTYLE },
+{ "old", IMPL_FONT_ATTR_OTHERSTYLE },
+{ "new", 0 },
+{ "modern", 0 },
+{ "lucida", 0 },
+{ "regular", 0 },
+{ "extended", 0 },
+{ "extra", IMPL_FONT_ATTR_OTHERSTYLE },
+{ "ext", 0 },
+{ "scalable", 0 },
+{ "scale", 0 },
+{ "nimbus", 0 },
+{ "adobe", 0 },
+{ "itc", 0 },
+{ "amt", 0 },
+{ "mt", 0 },
+{ "ms", 0 },
+{ "cpi", 0 },
+{ "no", 0 },
+{ NULL, 0 },
+};
+
+// -----------------------------------------------------------------------
+
+static bool ImplKillLeading( String& rName, const char* const* ppStr )
+{
+ for(; *ppStr; ++ppStr )
+ {
+ const char* pStr = *ppStr;
+ const xub_Unicode* pNameStr = rName.GetBuffer();
+ while ( (*pNameStr == (xub_Unicode)(unsigned char)*pStr) && *pStr )
+ {
+ pNameStr++;
+ pStr++;
+ }
+ if ( !*pStr )
+ {
+ xub_StrLen nLen = sal::static_int_cast<xub_StrLen>(pNameStr - rName.GetBuffer());
+ rName.Erase( 0, nLen );
+ return true;
+ }
+ }
+
+ // special case for Baekmuk
+ // TODO: allow non-ASCII KillLeading list
+ const xub_Unicode* pNameStr = rName.GetBuffer();
+ if( (pNameStr[0]==0xBC31) && (pNameStr[1]==0xBC35) )
+ {
+ xub_StrLen nLen = (pNameStr[2]==0x0020) ? 3 : 2;
+ rName.Erase( 0, nLen );
+ return true;
+ }
+
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+static xub_StrLen ImplIsTrailing( const String& rName, const char* pStr )
+{
+ xub_StrLen nStrLen = static_cast<xub_StrLen>( strlen( pStr ) );
+ if( nStrLen >= rName.Len() )
+ return 0;
+
+ const xub_Unicode* pEndName = rName.GetBuffer() + rName.Len();
+ const sal_Unicode* pNameStr = pEndName - nStrLen;
+ do if( *(pNameStr++) != *(pStr++) )
+ return 0;
+ while( *pStr );
+
+ return nStrLen;
+}
+
+// -----------------------------------------------------------------------
+
+static bool ImplKillTrailing( String& rName, const char* const* ppStr )
+{
+ for(; *ppStr; ++ppStr )
+ {
+ xub_StrLen nTrailLen = ImplIsTrailing( rName, *ppStr );
+ if( nTrailLen )
+ {
+ rName.Erase( rName.Len()-nTrailLen );
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+static bool ImplKillTrailingWithExceptions( String& rName, const char* const* ppStr )
+{
+ for(; *ppStr; ++ppStr )
+ {
+ xub_StrLen nTrailLen = ImplIsTrailing( rName, *ppStr );
+ if( nTrailLen )
+ {
+ // check string match against string exceptions
+ while( *++ppStr )
+ if( ImplIsTrailing( rName, *ppStr ) )
+ return false;
+
+ rName.Erase( rName.Len()-nTrailLen );
+ return true;
+ }
+ else
+ {
+ // skip exception strings
+ while( *++ppStr ) ;
+ }
+ }
+
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+static BOOL ImplFindAndErase( String& rName, const char* pStr )
+{
+ xub_StrLen nPos = rName.SearchAscii( pStr );
+ if ( nPos == STRING_NOTFOUND )
+ return FALSE;
+
+ const char* pTempStr = pStr;
+ while ( *pTempStr )
+ pTempStr++;
+ rName.Erase( nPos, (xub_StrLen)(pTempStr-pStr) );
+ return TRUE;
+}
+
+// =======================================================================
+
+void FontSubstConfiguration::getMapName( const String& rOrgName, String& rShortName,
+ String& rFamilyName, FontWeight& rWeight, FontWidth& rWidth, ULONG& rType )
+{
+ rShortName = rOrgName;
+
+ // TODO: get rid of the crazy O(N*strlen) searches below
+ // they should be possible in O(strlen)
+
+ // Kill leading vendor names and other unimportant data
+ ImplKillLeading( rShortName, aImplKillLeadingList );
+
+ // Kill trailing vendor names and other unimportant data
+ ImplKillTrailing( rShortName, aImplKillTrailingList );
+ ImplKillTrailingWithExceptions( rShortName, aImplKillTrailingWithExceptionsList );
+
+ rFamilyName = rShortName;
+
+ // Kill attributes from the name and update the data
+ // Weight
+ const ImplFontAttrWeightSearchData* pWeightList = aImplWeightAttrSearchList;
+ while ( pWeightList->mpStr )
+ {
+ if ( ImplFindAndErase( rFamilyName, pWeightList->mpStr ) )
+ {
+ if ( (rWeight == WEIGHT_DONTKNOW) || (rWeight == WEIGHT_NORMAL) )
+ rWeight = pWeightList->meWeight;
+ break;
+ }
+ pWeightList++;
+ }
+
+ // Width
+ const ImplFontAttrWidthSearchData* pWidthList = aImplWidthAttrSearchList;
+ while ( pWidthList->mpStr )
+ {
+ if ( ImplFindAndErase( rFamilyName, pWidthList->mpStr ) )
+ {
+ if ( (rWidth == WIDTH_DONTKNOW) || (rWidth == WIDTH_NORMAL) )
+ rWidth = pWidthList->meWidth;
+ break;
+ }
+ pWidthList++;
+ }
+
+ // Type
+ rType = 0;
+ const ImplFontAttrTypeSearchData* pTypeList = aImplTypeAttrSearchList;
+ while ( pTypeList->mpStr )
+ {
+ if ( ImplFindAndErase( rFamilyName, pTypeList->mpStr ) )
+ rType |= pTypeList->mnType;
+ pTypeList++;
+ }
+
+ // Remove numbers
+ // TODO: also remove localized and fullwidth digits
+ xub_StrLen i = 0;
+ while ( i < rFamilyName.Len() )
+ {
+ sal_Unicode c = rFamilyName.GetChar( i );
+ if ( (c >= 0x0030) && (c <= 0x0039) )
+ rFamilyName.Erase( i, 1 );
+ else
+ i++;
+ }
+}
+
+
+struct StrictStringSort : public ::std::binary_function< const FontNameAttr&, const FontNameAttr&, bool >
+{
+ bool operator()( const FontNameAttr& rLeft, const FontNameAttr& rRight )
+ { return rLeft.Name.CompareTo( rRight.Name ) == COMPARE_LESS ; }
+};
+
+static const char* const pAttribNames[] =
+{
+ "default",
+ "standard",
+ "normal",
+ "symbol",
+ "fixed",
+ "sansserif",
+ "serif",
+ "decorative",
+ "special",
+ "italic",
+ "title",
+ "capitals",
+ "cjk",
+ "cjk_jp",
+ "cjk_sc",
+ "cjk_tc",
+ "cjk_kr",
+ "ctl",
+ "nonelatin",
+ "full",
+ "outline",
+ "shadow",
+ "rounded",
+ "typewriter",
+ "script",
+ "handwriting",
+ "chancery",
+ "comic",
+ "brushscript",
+ "gothic",
+ "schoolbook",
+ "other"
+};
+
+struct enum_convert
+{
+ const char* pName;
+ int nEnum;
+};
+
+
+static const enum_convert pWeightNames[] =
+{
+ { "normal", WEIGHT_NORMAL },
+ { "medium", WEIGHT_MEDIUM },
+ { "bold", WEIGHT_BOLD },
+ { "black", WEIGHT_BLACK },
+ { "semibold", WEIGHT_SEMIBOLD },
+ { "light", WEIGHT_LIGHT },
+ { "semilight", WEIGHT_SEMILIGHT },
+ { "ultrabold", WEIGHT_ULTRABOLD },
+ { "semi", WEIGHT_SEMIBOLD },
+ { "demi", WEIGHT_SEMIBOLD },
+ { "heavy", WEIGHT_BLACK },
+ { "unknown", WEIGHT_DONTKNOW },
+ { "thin", WEIGHT_THIN },
+ { "ultralight", WEIGHT_ULTRALIGHT }
+};
+
+static const enum_convert pWidthNames[] =
+{
+ { "normal", WIDTH_NORMAL },
+ { "condensed", WIDTH_CONDENSED },
+ { "expanded", WIDTH_EXPANDED },
+ { "unknown", WIDTH_DONTKNOW },
+ { "ultracondensed", WIDTH_ULTRA_CONDENSED },
+ { "extracondensed", WIDTH_EXTRA_CONDENSED },
+ { "semicondensed", WIDTH_SEMI_CONDENSED },
+ { "semiexpanded", WIDTH_SEMI_EXPANDED },
+ { "extraexpanded", WIDTH_EXTRA_EXPANDED },
+ { "ultraexpanded", WIDTH_ULTRA_EXPANDED }
+};
+
+void FontSubstConfiguration::fillSubstVector( const com::sun::star::uno::Reference< XNameAccess > xFont,
+ const rtl::OUString& rType,
+ std::vector< String >& rSubstVector ) const
+{
+ try
+ {
+ Any aAny = xFont->getByName( rType );
+ if( aAny.getValueTypeClass() == TypeClass_STRING )
+ {
+ const OUString* pLine = (const OUString*)aAny.getValue();
+ sal_Int32 nIndex = 0;
+ sal_Int32 nLength = pLine->getLength();
+ if( nLength )
+ {
+ const sal_Unicode* pStr = pLine->getStr();
+ sal_Int32 nTokens = 0;
+ // count tokens
+ while( nLength-- )
+ {
+ if( *pStr++ == sal_Unicode(';') )
+ nTokens++;
+ }
+ rSubstVector.clear();
+ // optimize performance, heap fragmentation
+ rSubstVector.reserve( nTokens );
+ while( nIndex != -1 )
+ {
+ OUString aSubst( pLine->getToken( 0, ';', nIndex ) );
+ if( aSubst.getLength() )
+ {
+ UniqueSubstHash::iterator aEntry = maSubstHash.find( aSubst );
+ if (aEntry != maSubstHash.end())
+ aSubst = *aEntry;
+ else
+ maSubstHash.insert( aSubst );
+ rSubstVector.push_back( aSubst );
+ }
+ }
+ }
+ }
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+}
+
+FontWeight FontSubstConfiguration::getSubstWeight( const com::sun::star::uno::Reference< XNameAccess > xFont,
+ const rtl::OUString& rType ) const
+{
+ int weight = -1;
+ try
+ {
+ Any aAny = xFont->getByName( rType );
+ if( aAny.getValueTypeClass() == TypeClass_STRING )
+ {
+ const OUString* pLine = (const OUString*)aAny.getValue();
+ if( pLine->getLength() )
+ {
+ for( weight=sizeof(pWeightNames)/sizeof(pWeightNames[0])-1; weight >= 0; weight-- )
+ if( pLine->equalsIgnoreAsciiCaseAscii( pWeightNames[weight].pName ) )
+ break;
+ }
+#if OSL_DEBUG_LEVEL > 1
+ if( weight < 0 )
+ fprintf( stderr, "Error: invalid weight %s\n",
+ OUStringToOString( *pLine, RTL_TEXTENCODING_ASCII_US ).getStr() );
+#endif
+ }
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+ return (FontWeight)( weight >= 0 ? pWeightNames[weight].nEnum : WEIGHT_DONTKNOW );
+}
+
+FontWidth FontSubstConfiguration::getSubstWidth( const com::sun::star::uno::Reference< XNameAccess > xFont,
+ const rtl::OUString& rType ) const
+{
+ int width = -1;
+ try
+ {
+ Any aAny = xFont->getByName( rType );
+ if( aAny.getValueTypeClass() == TypeClass_STRING )
+ {
+ const OUString* pLine = (const OUString*)aAny.getValue();
+ if( pLine->getLength() )
+ {
+ for( width=sizeof(pWidthNames)/sizeof(pWidthNames[0])-1; width >= 0; width-- )
+ if( pLine->equalsIgnoreAsciiCaseAscii( pWidthNames[width].pName ) )
+ break;
+ }
+#if OSL_DEBUG_LEVEL > 1
+ if( width < 0 )
+ fprintf( stderr, "Error: invalid width %s\n",
+ OUStringToOString( *pLine, RTL_TEXTENCODING_ASCII_US ).getStr() );
+#endif
+ }
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+ return (FontWidth)( width >= 0 ? pWidthNames[width].nEnum : WIDTH_DONTKNOW );
+}
+
+unsigned long FontSubstConfiguration::getSubstType( const com::sun::star::uno::Reference< XNameAccess > xFont,
+ const rtl::OUString& rType ) const
+{
+ unsigned long type = 0;
+ try
+ {
+ Any aAny = xFont->getByName( rType );
+ if( aAny.getValueTypeClass() == TypeClass_STRING )
+ {
+ const OUString* pLine = (const OUString*)aAny.getValue();
+ if( pLine->getLength() )
+ {
+ sal_Int32 nIndex = 0;
+ while( nIndex != -1 )
+ {
+ String aToken( pLine->getToken( 0, ',', nIndex ) );
+ for( int k = 0; k < 32; k++ )
+ if( aToken.EqualsIgnoreCaseAscii( pAttribNames[k] ) )
+ {
+ type |= 1 << k;
+ break;
+ }
+ }
+ }
+ }
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+
+ return type;
+}
+
+void FontSubstConfiguration::readLocaleSubst( const com::sun::star::lang::Locale& rLocale ) const
+{
+ std::hash_map< Locale, LocaleSubst, LocaleHash >::const_iterator it =
+ m_aSubst.find( rLocale );
+ if( it != m_aSubst.end() )
+ {
+ if( ! it->second.bConfigRead )
+ {
+ it->second.bConfigRead = true;
+ Reference< XNameAccess > xNode;
+ try
+ {
+ Any aAny = m_xConfigAccess->getByName( it->second.aConfigLocaleString );
+ aAny >>= xNode;
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+ if( xNode.is() )
+ {
+ Sequence< OUString > aFonts = xNode->getElementNames();
+ int nFonts = aFonts.getLength();
+ const OUString* pFontNames = aFonts.getConstArray();
+ // improve performance, heap fragmentation
+ it->second.aSubstAttributes.reserve( nFonts );
+
+ // strings for subst retrieval, construct only once
+ OUString aSubstFontsStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFonts" ) );
+ OUString aSubstFontsMSStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsMS" ) );
+ OUString aSubstFontsPSStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsPS" ) );
+ OUString aSubstFontsHTMLStr ( RTL_CONSTASCII_USTRINGPARAM( "SubstFontsHTML" ) );
+ OUString aSubstWeightStr ( RTL_CONSTASCII_USTRINGPARAM( "FontWeight" ) );
+ OUString aSubstWidthStr ( RTL_CONSTASCII_USTRINGPARAM( "FontWidth" ) );
+ OUString aSubstTypeStr ( RTL_CONSTASCII_USTRINGPARAM( "FontType" ) );
+ for( int i = 0; i < nFonts; i++ )
+ {
+ Reference< XNameAccess > xFont;
+ try
+ {
+ Any aAny = xNode->getByName( pFontNames[i] );
+ aAny >>= xFont;
+ }
+ catch( NoSuchElementException )
+ {
+ }
+ catch( WrappedTargetException )
+ {
+ }
+ if( ! xFont.is() )
+ {
+ #if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "did not get font attributes for %s\n",
+ OUStringToOString( pFontNames[i], RTL_TEXTENCODING_UTF8 ).getStr() );
+ #endif
+ continue;
+ }
+
+ FontNameAttr aAttr;
+ // read subst attributes from config
+ aAttr.Name = pFontNames[i];
+ fillSubstVector( xFont, aSubstFontsStr, aAttr.Substitutions );
+ fillSubstVector( xFont, aSubstFontsMSStr, aAttr.MSSubstitutions );
+ fillSubstVector( xFont, aSubstFontsPSStr, aAttr.PSSubstitutions );
+ fillSubstVector( xFont, aSubstFontsHTMLStr, aAttr.HTMLSubstitutions );
+ aAttr.Weight = getSubstWeight( xFont, aSubstWeightStr );
+ aAttr.Width = getSubstWidth( xFont, aSubstWidthStr );
+ aAttr.Type = getSubstType( xFont, aSubstTypeStr );
+
+ // finally insert this entry
+ it->second.aSubstAttributes.push_back( aAttr );
+ }
+ std::sort( it->second.aSubstAttributes.begin(), it->second.aSubstAttributes.end(), StrictStringSort() );
+ }
+ }
+ }
+}
+
+const FontNameAttr* FontSubstConfiguration::getSubstInfo( const String& rFontName, const Locale& rLocale ) const
+{
+ if( !rFontName.Len() )
+ return NULL;
+
+ // search if a (language dep.) replacement table for the given font exists
+ // fallback is english
+ String aSearchFont( rFontName );
+ aSearchFont.ToLowerAscii();
+ FontNameAttr aSearchAttr;
+ aSearchAttr.Name = aSearchFont;
+
+ Locale aLocale;
+ aLocale.Language = rLocale.Language.toAsciiLowerCase();
+ aLocale.Country = rLocale.Country.toAsciiUpperCase();
+ aLocale.Variant = rLocale.Variant.toAsciiUpperCase();
+
+ if( ! aLocale.Language.getLength() )
+ aLocale = SvtSysLocale().GetUILocale();
+
+ while( aLocale.Language.getLength() )
+ {
+ std::hash_map< Locale, LocaleSubst, LocaleHash >::const_iterator lang = m_aSubst.find( aLocale );
+ if( lang != m_aSubst.end() )
+ {
+ if( ! lang->second.bConfigRead )
+ readLocaleSubst( aLocale );
+ // try to find an exact match
+ // because the list is sorted this will also find fontnames of the form searchfontname*
+ std::vector< FontNameAttr >::const_iterator it = ::std::lower_bound( lang->second.aSubstAttributes.begin(), lang->second.aSubstAttributes.end(), aSearchAttr, StrictStringSort() );
+ if( it != lang->second.aSubstAttributes.end() && aSearchFont.CompareTo( it->Name, aSearchFont.Len() ) == COMPARE_EQUAL )
+ return &(*it);
+ }
+ // gradually become more unspecific
+ if( aLocale.Variant.getLength() )
+ aLocale.Variant = OUString();
+ else if( aLocale.Country.getLength() )
+ aLocale.Country = OUString();
+ else if( ! aLocale.Language.equalsAscii( "en" ) )
+ aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) );
+ else
+ aLocale.Language = OUString();
+ }
+ return NULL;
+}
+
diff --git a/unotools/source/config/makefile.mk b/unotools/source/config/makefile.mk
index eee8d4af9d73..de87d9503339 100644
--- a/unotools/source/config/makefile.mk
+++ b/unotools/source/config/makefile.mk
@@ -62,6 +62,7 @@ SLOFILES=\
$(SLO)$/eventcfg.obj \
$(SLO)$/extendedsecurityoptions.obj \
$(SLO)$/fltrcfg.obj \
+ $(SLO)$/fontcfg.obj \
$(SLO)$/fontoptions.obj \
$(SLO)$/historyoptions.obj \
$(SLO)$/inetoptions.obj \
diff --git a/unotools/source/misc/fontcvt.cxx b/unotools/source/misc/fontcvt.cxx
new file mode 100644
index 000000000000..5c4f902fbd55
--- /dev/null
+++ b/unotools/source/misc/fontcvt.cxx
@@ -0,0 +1,1523 @@
+/*************************************************************************
+ *
+ * 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: fontcvt.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * 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_unotools.hxx"
+#include <unotools/fontcvt.hxx>
+#include <unotools/fontdefs.hxx>
+
+#ifndef _STLP_MAP
+#include <map>
+#endif
+#ifndef _STLP_VECTOR
+#include <vector>
+#endif
+#ifndef _STLP_ALGORITHM
+#include <algorithm>
+#endif
+#ifndef _STLP_FUNCTIONAL
+#include <functional>
+#endif
+
+//=======================================================================
+// note: the character mappings that are only approximations
+// are marked (with an empty comment)
+
+static const sal_Unicode aStarBatsTab[224] =
+{
+ // F020
+ 0x0020, 0x263a, 0x25cf, 0x274d,
+ 0x25a0, 0x25a1, 0xE000, 0x2751,
+ 0x2752, 0xE001, 0xE002, 0xE003,
+ 0x2756, 0xE004, 0xE005, 0x27a2,
+ // F030
+ 0xE006, 0x2794, 0x2713, 0x2612,
+ 0x2611, 0x27b2, 0x261b, 0x270d,
+ 0x270e, 0xE007, 0x2714, 0xE008,
+ 0xE009, 0xE00A, 0x274f, 0x2750,
+ // F040
+ 0xE00B, 0xE00C, 0xE00D, 0xE00E,
+ 0x2722, 0x2723, 0x2724, 0x2725,
+ 0x2733, 0x2734, 0x2735, 0x2736,
+ 0x2737, 0x2738, 0x2739, 0x2717,
+ // F050
+ 0x2718, 0x2719, 0x271a, 0x271b,
+ 0x271c, 0x272b, 0x272c, 0x272d,
+ 0x272e, 0x272f, 0x2730, 0,
+ 0xE00F, 0x278a, 0x278b, 0x278c,
+ // F060
+ 0x278d, 0x278e, 0x278f, 0x2790,
+ 0x2791, 0x2792, 0x2793, 0xE010,
+ 0x2780, 0x2781, 0x2782, 0x2783,
+ 0x2784, 0x2785, 0x2786, 0x2787,
+ // F070
+ 0x2788, 0x2789, 0xE011, 0xE012,
+ 0x260e, 0xE013, 0xE014, 0xE015,
+ 0xE016, 0xE017, 0xE018, 0xE019,
+ 0xE01A, 0x261e, 0xE01B, 0,
+ // F080
+ 0x20ac, 0, 0x201a, 0x0192,
+ 0x201e, 0x2026, 0x2020, 0x2021,
+ 0xE01c, 0x2030, 0x0160, 0x2039,
+ 0x0152, 0, 0x017d, 0,
+ // F090
+ 0, 0x2018, 0x2019, 0x201c,
+ 0x201d, 0x2022, 0x2013, 0x2014,
+ 0xE01d, 0x2122, 0x0161, 0x203a,
+ 0x0153, 0, 0x017e, 0x0178,
+ // F0A0
+ 0, 0x21e7, 0x21e8, 0x21e9,
+ 0x21e6, 0xE01e, 0xE01f, 0x00a7,
+ 0xE020, 0xE021, 0xE022, 0x00ab,
+ 0xE023, 0x2639, 0xE024, 0xE025,
+ // F0B0
+ 0xE026, 0xE027, 0xE028, 0x21e5,
+ 0x21e4, 0x2192, 0x2193, 0x2190,
+ 0x2191, 0xE029, 0xE02a, 0x00bb,
+ 0xE02b, 0xE02c, 0xE02d, 0xE02e,
+ // F0C0
+ 0xE02f, 0xE030, 0xE031, 0xE032,
+ 0x25be, 0x25b4, 0x25bf, 0x25b5,
+ 0xE033, 0xE034, 0xE035, 0x2702,
+ 0x2708, 0x2721, 0x273f, 0x2744,
+ // F0D0
+ 0x25d7, 0x2759, 0xE036, 0xE037,
+ 0x2762, 0x2663, 0x2665, 0x2660,
+ 0x2194, 0x2195, 0x2798, 0x279a,
+ 0x27b8, 0, 0x00b6, 0,
+ // F0E0
+ 0x00a2, 0x00a4, 0x00a5, 0xE038,
+ 0x20a1, 0x20a2, 0x20a3, 0x20a4,
+ 0x20a9, 0x20ab, 0x20a8, 0xE039,
+ 0, 0, 0, 0,
+ // F0F0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0xE03a
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aStarMathTab[224] =
+{
+ // F020
+ 0x0020, 0x0021, 0x0022, 0x0023,
+ 0xE080, 0x0025, 0x0026, 0x221e,
+ 0x0028, 0x0029, 0x002a, 0x002b,
+ 0x002c, 0x002d, 0x002e, 0x002f,
+ // F030
+ 0x2224, 0x21d2, 0x21d0, 0x21d4,
+ 0xE081, 0xE082, 0x00b0, 0,
+ 0, 0, 0x003a, 0x003b,
+ 0x003c, 0x003d, 0x003e, 0x00bf,
+ // F040
+ 0x2260, 0xE083, 0x2212, 0x2217,
+ 0x00d7, 0x22c5, 0x00f7, 0x00b1,
+ 0x2213, 0x2295, 0x2296, 0x2297,
+ 0x2298, 0x2299, 0x222a, 0x2229,
+ // F050
+ 0xE084, 0xE085, 0x2264, 0x2265,
+ 0xE086, 0xE087, 0x226a, 0x226b,
+ 0x007e, 0x2243, 0x2248, 0x225d,
+ 0x2261, 0x221d, 0x2202, 0x2282,
+ // F060
+ 0x2283, 0x2286, 0x2287, 0x2284,
+ 0x2285, 0x2288, 0x2289, 0x2208,
+ 0x2209, 0xE089, 0x2203, 0x220d,
+ 0x2135, 0x2111, 0x211c, 0x2118,
+ // F070
+ 0xE08a, 0x2221, 0x2222, 0x2223,
+ 0x2225, 0x22a5, 0xE08b, 0x22ef,
+ 0x22ee, 0x22f0, 0x22f1, 0x22b6,
+ 0x22b7, 0xE08c, 0x2216, 0x00ac,
+ // F080
+ 0x222b, 0x222c, 0x222d, 0x222e,
+ 0x222f, 0x2230, 0x221a, 0xE08d,
+ 0xE08e, 0xE08f, 0x2210, 0x220f,
+ 0x2211, 0x2207, 0x2200, 0xE090,
+ // F090
+ 0xE091, 0xE092, 0xE093, 0xE094,
+ 0xE095, 0xE096, 0xE097, 0xE098,
+ 0x02d9, 0x00a8, 0xE09b, 0x02da,
+ 0x2227, 0x2228, 0x220b, 0x2205,
+ // F0A0
+ 0x007b, 0x007d, 0xe09e, 0xe09f,
+ 0x2329, 0x232a, 0x005b, 0x005d,
+ 0xE0a0, 0x22be, 0xE0a1, 0x2259,
+ 0x2254, 0x2255, 0x21b3, 0x2197,
+ // F0B0
+ 0x2198, 0x2245, 0x301a, 0x301b,
+ 0x2373, 0xE0a5, 0xE0a6, 0x22a4,
+ 0x2112, 0x2130, 0x2131, 0,
+ 0xE0a7, 0xE0a8, 0xE0a9, 0xE0aa,
+ // F0C0
+ 0x2308, 0x230a, 0x2309, 0x230b,
+ 0, 0xe0ab, 0xe0ac, 0xe0ad,
+ 0xe0ae, 0xe0af, 0xe0b0, 0xe0b1,
+ 0xe0b2, 0xe0b3, 0xe0b4, 0xe0b5,
+ // F0D0
+ 0xe0b6, 0xe0b7, 0xe0b8, 0xe0b9,
+ 0xe0ba, 0xe0bb, 0xe0bc, 0xe0bd,
+ 0xe0be, 0xe0bf, 0xe0c0, 0xe0c1,
+ 0xe0c2, 0xe0c3, 0xe0c4, 0xe0c5,
+ // F0E0
+ 0xe0c6, 0xe0c7, 0xe0c8, 0xe0c9,
+ 0xe0ca, 0xe0cb, 0xe0cc, 0xe0cd,
+ 0xe0ce, 0xe0cf, 0xe0d0, 0xe0d1,
+ 0x03f1, 0xe0d3, 0xe0d4, 0xe0d5,
+ // F0F0
+ 0x2113, 0xe0d6, 0x2107, 0x2127,
+ 0x210a, 0xe0d9, 0x210f, 0x019b,
+ 0xe0db, 0xe0dc, 0xe0dd, 0x2115,
+ 0x2124, 0x211a, 0x211d, 0x2102
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aWingDingsTab[224] =
+{
+ // F020
+ 0x0020, 0xe400, 0xe401, 0xe402,
+ 0xe403, 0xe404, 0xe405, 0xe406,
+ 0xe407, 0xe408, 0xe409, 0xe40a,
+ 0xe40b, 0xe40c, 0xe40d, 0xe40e,
+ // F030
+ 0xe40f, 0xe410, 0xe411, 0xe412,
+ 0xe413, 0xe414, 0xe415, 0xe416,
+ 0xe417, 0xe418, 0xe419, 0xe41a,
+ 0xe41b, 0xe41c, 0x2707, 0xe41d,
+ // F040
+ 0xe41e, 0xe41f, 0xe420, 0xe421,
+ 0x261c, 0xe423, 0x261d, 0x261f,
+ 0x261f, 0xe424, 0xe425, 0xe426,
+ 0xe427, 0xe428, 0xe429, 0xe42a,
+ // F050
+ 0xe42b, 0xe42c, 0x263c, 0xe42d,
+ 0xe42e, 0xe42f, 0xe430, 0xe431,
+ 0xe432, 0xe433, 0x262a, 0x262f,
+ 0x0950, 0xe434, 0x2648, 0x2649,
+ // F060
+ 0x264a, 0x264b, 0x264c, 0x264d,
+ 0x264e, 0x264f, 0x2650, 0x2651,
+ 0x2652, 0x2653, 0xe435, 0xe436,
+ 0xe437, 0xe438, 0xe439, 0xe43a,
+ // F070
+ 0xe43b, 0xe43c, 0xe43d, 0xe43e,
+ 0xe43f, 0xe440, 0xe441, 0xe442,
+ 0xe443, 0x2353, 0x2318, 0xe444,
+ 0xe445, 0xe446, 0xe447, 0,
+ // F080
+ 0xe448, 0xe449, 0xe44a, 0xe44b,
+ 0xe44c, 0xe44d, 0xe44e, 0xe44f,
+ 0xe450, 0xe451, 0xe452, 0xe453,
+ 0xe454, 0xe455, 0xe456, 0xe457,
+ // F090
+ 0xe458, 0xe459, 0xe45a, 0xe45b,
+ 0xe45c, 0xe45d, 0xe45e, 0xe45f,
+ 0xe460, 0xe461, 0xe462, 0xe463,
+ 0xe464, 0xe465, 0xe466, 0xe467,
+ // F0a0
+ 0xe468, 0xe469, 0xe46a, 0xe46b,
+ 0xe46c, 0xe46d, 0xe46e, 0xe46f,
+ 0xe470, 0xe471, 0xe472, 0xe473,
+ 0xe474, 0xe475, 0xe476, 0xe477,
+ // F0b0
+ 0xe478, 0xe479, 0xe47a, 0xe47b,
+ 0xe47c, 0xe47d, 0xe47e, 0xe47f,
+ 0xe480, 0xe481, 0xe482, 0xe483,
+ 0xe484, 0xe485, 0xe486, 0xe487,
+ // F0c0
+ 0xe488, 0xe489, 0xe48a, 0xe48b,
+ 0xe48c, 0xe48d, 0xe48e, 0xe48f,
+ 0xe490, 0xe491, 0xe492, 0xe493,
+ 0xe494, 0xe495, 0xe496, 0xe497,
+ // F0d0
+ 0xe498, 0xe499, 0xe49a, 0xe49b,
+ 0xe49c, 0x232b, 0x2326, 0xe49d,
+ 0xe49e, 0xe49f, 0xe4a0, 0xe4a1,
+ 0xe4a2, 0xe4a3, 0xe4a4, 0xe4a5,
+ // F0e0
+ 0xe4a6, 0xe4a7, 0xe4a8, 0xe4a9,
+ 0xe4aa, 0xe4ab, 0xe4ac, 0xe4ad,
+ 0xe4ae, 0xe4af, 0xe4b0, 0xe4b1,
+ 0xe4b2, 0xe4b3, 0xe4b4, 0xe4b5,
+ // F0f0
+ 0xe4b6, 0xe4b7, 0xe4b8, 0xe4b9,
+ 0xe4ba, 0xe4bb, 0xe4bc, 0xe4bd,
+ 0xe4be, 0xe4bf, 0xe4c0, 0xe4c1,
+ 0xe4c2, 0xe4c3, 0xe4c4, 0xe4c5
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aWingDings2Tab[224] =
+{
+ // F020
+ 0x0020, 0xe500, 0xe501, 0xe502,
+ 0xe503, 0xe504, 0xe505, 0xe506,
+ 0xe507, 0xe508, 0xe509, 0xe50a,
+ 0xe50b, 0xe50c, 0xe50d, 0xe50e,
+ // F030
+ 0xe50f, 0xe510, 0xe511, 0xe512,
+ 0xe513, 0xe514, 0xe515, 0xe516,
+ 0xe517, 0xe518, 0xe519, 0xe51a,
+ 0xe51b, 0xe51c, 0xe51d, 0xe51e,
+ // F040
+ 0xe51f, 0xe520, 0xe521, 0xe522,
+ 0xe523, 0xe524, 0xe525, 0xe526,
+ 0xe527, 0xe528, 0xe529, 0xe52a,
+ 0xe52b, 0xe52c, 0xe52d, 0xe52e,
+ // F050
+ 0xe52f, 0xe530, 0xe531, 0xe532,
+ 0xe533, 0xe534, 0xe535, 0xe536,
+ 0xe537, 0xe538, 0xe539, 0xe53a,
+ 0xe53b, 0xe53c, 0xe53d, 0xe53e,
+ // F060
+ 0xe53f, 0xe540, 0xe541, 0xe542,
+ 0xe543, 0xe544, 0xe545, 0xe546,
+ 0xe547, 0xe548, 0xe549, 0xe54a,
+ 0xe54b, 0xe54c, 0xe54d, 0xe54e,
+ // F070
+ 0xe54e, 0xe54f, 0xe550, 0xe551,
+ 0xe552, 0xe553, 0xe554, 0xe555,
+ 0xe556, 0xe557, 0xe558, 0xe559,
+ 0xe55a, 0xe55b, 0xe55c, 0,
+ // F080
+ 0x2609, 0x25cb, 0x263d, 0x263e,
+ 0xe55d, 0xe55e, 0xe55f, 0xe560,
+ 0xe561, 0xe562, 0xe563, 0xe564,
+ 0xe565, 0xe566, 0xe567, 0xe568,
+ // F090
+ 0xe569, 0xe56a, 0xe56b, 0xe56c,
+ 0xe56d, 0xe56e, 0xe56f, 0xe570,
+ 0xe571, 0xe572, 0xe573, 0xe574,
+ 0xe575, 0xe576, 0xe577, 0xe578,
+ // F0a0
+ 0xe579, 0xe57a, 0xe57b, 0xe57c,
+ 0xe57d, 0xe57e, 0xe57f, 0xe580,
+ 0xe581, 0xe582, 0xe583, 0xe584,
+ 0xe585, 0xe586, 0xe587, 0xe588,
+ // F0b0
+ 0xe589, 0xe58a, 0xe58b, 0xe58c,
+ 0xe58d, 0xe58e, 0xe58f, 0xe590,
+ 0xe591, 0xe592, 0xe593, 0xe594,
+ 0xe595, 0xe596, 0xe597, 0xe598,
+ // F0c0
+ 0xe599, 0xe59a, 0xe59b, 0xe59c,
+ 0xe59d, 0xe59e, 0xe59f, 0xe5a0,
+ 0xe5a1, 0xe5a2, 0xe5a3, 0xe5a4,
+ 0xe5a5, 0xe5a6, 0xe5a7, 0xe5a8,
+ // F0d0
+ 0xe5a9, 0xe5aa, 0xe5ab, 0xe5ac,
+ 0xe5ad, 0xe5ae, 0xe5af, 0xe5b0,
+ 0xe5b1, 0xe5b2, 0xe5b3, 0xe5b4,
+ 0xe5b5, 0xe5b6, 0xe5b7, 0xe5b8,
+ // F0e0
+ 0xe5b9, 0xe5ba, 0xe5bb, 0xe5bc,
+ 0xe5bd, 0xe5be, 0xe5bf, 0xe5c0,
+ 0xe5c1, 0xe5c2, 0xe5c3, 0xe5c4,
+ 0xe5c5, 0xe5c6, 0xe5c7, 0xe5c8,
+ // F0f0
+ 0xe5c9, 0xe5ca, 0xe5cb, 0xe5cc,
+ 0xe5cd, 0xe5ce, 0xe5cf, 0xe5d0,
+ 0x203b, 0x2042, 0, 0,
+ 0, 0, 0, 0
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aWingDings3Tab[224] =
+{
+ // F020
+ 0x0020, 0xe600, 0xe601, 0xe602,
+ 0xe603, 0x2196, 0xe604, 0x2199,
+ 0xe605, 0xe606, 0xe607, 0xe608,
+ 0xe609, 0xe60a, 0xe60b, 0x21de,
+ // F030
+ 0x21df, 0xe60c, 0xe60d, 0xe60e,
+ 0x21e2, 0x21e1, 0x21e3, 0x21af,
+ 0x21b5, 0xe60f, 0xe610, 0xe611,
+ 0xe612, 0xe613, 0xe614, 0xe615,
+ // F040
+ 0xe616, 0xe617, 0xe618, 0xe619,
+ 0x21c4, 0x21c5, 0xe61a, 0xe61b,
+ 0x21c7, 0x21c9, 0x21c8, 0x21ca,
+ 0x21b6, 0x21b7, 0xe61c, 0xe61d,
+ // F050
+ 0x21bb, 0x21ba, 0xe61e, 0x2324,
+ 0x2303, 0x2325, 0x2334, 0xe61f,
+ 0x21ea, 0xe620, 0xe621, 0xe622,
+ 0xe623, 0xe624, 0xe625, 0xe626,
+ // F060
+ 0xe627, 0xe628, 0xe629, 0xe62a,
+ 0xe62b, 0xe62c, 0xe62d, 0xe62e,
+ 0xe62f, 0xe630, 0xe631, 0xe632,
+ 0xe633, 0xe634, 0xe635, 0xe636,
+ // F070
+ 0xe637, 0xe638, 0x25b3, 0x25bd,
+ 0x25c0, 0x25b6, 0x25c1, 0x25b7,
+ 0x25e3, 0xe639, 0x25e4, 0x25e5,
+ 0x25c2, 0x25b8, 0xe63a, 0,
+ // F080
+ 0xe63b, 0xe63c, 0xe63d, 0xe63e,
+ 0xe63f, 0xe640, 0xe641, 0xe642,
+ 0xe643, 0xe644, 0xe645, 0xe646,
+ 0xe647, 0xe648, 0xe649, 0xe64a,
+ // F090
+ 0xe64b, 0xe64c, 0xe64d, 0xe64e,
+ 0xe64f, 0xe650, 0xe651, 0xe652,
+ 0xe653, 0xe654, 0xe655, 0xe656,
+ 0xe657, 0xe658, 0xe659, 0xe65a,
+ // F0a0
+ 0xe65b, 0xe65c, 0xe65d, 0xe65e,
+ 0xe65f, 0xe660, 0xe661, 0xe662,
+ 0xe663, 0xe664, 0xe665, 0xe666,
+ 0xe667, 0xe668, 0xe669, 0xe66a,
+ // F0b0
+ 0xe66b, 0xe66c, 0xe66d, 0xe66e,
+ 0xe66f, 0xe670, 0xe671, 0xe672,
+ 0xe673, 0xe674, 0xe675, 0xe676,
+ 0xe677, 0xe678, 0xe679, 0xe67a,
+ // F0c0
+ 0xe67b, 0xe67c, 0xe67d, 0xe67e,
+ 0xe67f, 0xe680, 0xe681, 0xe682,
+ 0xe683, 0xe684, 0xe685, 0xe686,
+ 0xe687, 0xe688, 0xe689, 0xe68a,
+ // F0d0
+ 0xe68b, 0xe68c, 0xe68d, 0xe68e,
+ 0xe68f, 0xe690, 0xe691, 0xe692,
+ 0xe693, 0xe694, 0xe695, 0xe696,
+ 0xe697, 0xe698, 0xe699, 0xe69a,
+ // F0e0
+ 0xe69b, 0xe69c, 0xe69d, 0xe69e,
+ 0xe69f, 0xe6a0, 0xe6a1, 0xe6a2,
+ 0xe6a3, 0xe6a4, 0xe6a5, 0xe6a6,
+ 0xe6a7, 0xe6a8, 0xe6a9, 0xe6aa,
+ // F0f0
+ 0xe6ab, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aWebDingsTab[224] =
+{
+ // F020
+ 0x0020, 0xe300, 0xe301, 0xe302,
+ 0xe303, 0xe304, 0xe305, 0xe306,
+ 0xe307, 0xe308, 0xe309, 0xe30a,
+ 0xe30b, 0xe30c, 0xe30d, 0xe30e,
+ // F030
+ 0xe30f, 0xe310, 0xe311, 0xe312,
+ 0xe313, 0xe314, 0xe315, 0xe316,
+ 0xe317, 0xe318, 0xe319, 0xe31a,
+ 0xe31b, 0xe31c, 0xe31d, 0xe31e,
+ // F040
+ 0xe31f, 0xe320, 0xe321, 0xe322,
+ 0xe323, 0xe324, 0xe325, 0xe326,
+ 0xe327, 0xe328, 0xe329, 0xe32a,
+ 0xe32b, 0xe32c, 0xe32d, 0xe32e,
+ // F050
+ 0xe32f, 0xe330, 0xe331, 0xe332,
+ 0xe333, 0xe334, 0xe335, 0xe336,
+ 0xe337, 0xe338, 0xe339, 0xe33a,
+ 0xe33b, 0xe33c, 0xe33d, 0xe33e,
+ // F060
+ 0xe33f, 0xe340, 0xe341, 0xe342,
+ 0xe343, 0xe344, 0xe345, 0xe346,
+ 0xe347, 0xe348, 0xe349, 0xe34a,
+ 0xe34b, 0xe34c, 0xe34d, 0xe34e,
+ // F070
+ 0xe34f, 0xe350, 0xe351, 0xe352,
+ 0xe353, 0xe354, 0xe355, 0xe356,
+ 0xe357, 0xe358, 0xe359, 0xe35a,
+ 0xe35b, 0xe35c, 0xe35d, 0,
+ // F080
+ 0xe35e, 0xe35f, 0xe360, 0xe361,
+ 0xe362, 0xe363, 0xe364, 0xe365,
+ 0xe366, 0xe367, 0xe368, 0xe369,
+ 0xe36a, 0xe36b, 0xe36c, 0xe36d,
+ // F090
+ 0xe36e, 0xe36f, 0xe370, 0xe371,
+ 0xe372, 0xe373, 0xe374, 0xe375,
+ 0xe376, 0xe377, 0xe378, 0xe379,
+ 0xe37a, 0xe37b, 0xe37c, 0xe37d,
+ // F0a0
+ 0xe37e, 0xe37f, 0xe380, 0xe381,
+ 0xe382, 0xe383, 0xe384, 0xe385,
+ 0xe386, 0xe387, 0xe388, 0xe389,
+ 0xe38a, 0xe38b, 0xe38c, 0xe38d,
+ // F0b0
+ 0xe38e, 0xe38f, 0xe390, 0xe391,
+ 0xe392, 0xe393, 0xe394, 0xe395,
+ 0xe396, 0xe397, 0xe398, 0xe399,
+ 0xe39a, 0xe39b, 0xe39c, 0xe39d,
+ // F0c0
+ 0xe39e, 0xe39f, 0xe3a0, 0xe3a1,
+ 0xe3a2, 0xe3a3, 0xe3a4, 0xe3a5,
+ 0xe3a6, 0xe3a7, 0xe3a8, 0xe3a9,
+ 0xe3aa, 0xe3ab, 0xe3ac, 0xe3ad,
+ // F0d0
+ 0xe3ae, 0xe3af, 0xe3b0, 0xe3b1,
+ 0xe3b2, 0xe3b3, 0xe3b4, 0xe3b5,
+ 0xe3b6, 0xe3b7, 0xe3b8, 0xe3b9,
+ 0xe3ba, 0xe3bb, 0xe3bc, 0xe3bd,
+ // F0e0
+ 0xe3be, 0xe3bf, 0xe3c0, 0xe3c1,
+ 0xe3c2, 0xe3c3, 0xe3c4, 0xe3c5,
+ 0xe3c6, 0xe3c7, 0xe3c8, 0xe3c9,
+ 0xe3ca, 0xe3cb, 0xe3cd, 0xe3ce,
+ // F0f0
+ 0xe3cf, 0xe3d0, 0xe3d1, 0xe3d2,
+ 0xe3d3, 0xe3d4, 0xe3d5, 0xe3d6,
+ 0xe3d7, 0xe3d8, 0xe3d9, 0xe3da,
+ 0xe3db, 0xe3dc, 0xe3dd, 0xe3de
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aAdobeSymbolTab[224] =
+{
+//TODO:
+ // F020
+ 0x0020, 0xe100, 0xe101, 0xe102,
+ 0xe103, 0xe104, 0xe16a, 0xe105,
+ 0xe106, 0xe107, 0xe108, 0xe109,
+ 0xe10a, 0xe10b, 0xe10c, 0xe10d,
+ // F030
+ 0x0030, 0x0031, 0x0032, 0x0033,
+ 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0xe10e, 0xe10f,
+ 0xe110, 0xe111, 0xe112, 0x003f,
+ // F040
+ 0xe113, 0x0391, 0x0392, 0x03a7,
+ 0x0394, 0x0395, 0x03a6, 0x0393,
+ 0x0397, 0x0399, 0x03d1, 0x039a,
+ 0x039b, 0x039c, 0x039d, 0x039f,
+ // F050
+ 0x03a0, 0x0398, 0x03a1, 0x03a3,
+ 0x03a4, 0x03a5, 0x03c2, 0x03a9,
+ 0x039e, 0x03a8, 0x0396, 0xe114,
+ 0x2234, 0xe115, 0xe116, 0x005f,
+ // F060
+ 0x00af, 0x03b1, 0x03b2, 0x03c7,
+ 0x03b4, 0x03b5, 0x03d5, 0x03b3,
+ 0x03b7, 0x03b9, 0x03c6, 0x03ba,
+ 0x03bb, 0x03bc, 0x03bd, 0x03bf,
+ // F070
+ 0x03c0, 0x03b8, 0x03c1, 0x03c3,
+ 0x03c4, 0x03c5, 0x03d6, 0x03c9,
+ 0x03be, 0x03c8, 0x03b6, 0xe117,
+ 0x007c, 0xe118, 0xe119, 0,
+ // F080
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F090
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0a0
+ 0xe11a, 0x03d2, 0x0384, 0xe11b,
+ 0x2215, 0xe11c, 0xe11d, 0xe11e,
+ 0x2666, 0xe11f, 0xe120, 0xe121,
+ 0xe122, 0xe123, 0xe124, 0xe125,
+ // F0b0
+ 0xe126, 0xe127, 0x2033, 0xe128,
+ 0xe129, 0xe12a, 0xe12b, 0xe12c,
+ 0xe12d, 0xe12e, 0xe12f, 0xe130,
+ 0xe131, 0x2502, 0x2500, 0x21b2,
+ // F0c0
+ 0xe132, 0xe133, 0xe134, 0xe135,
+ 0xe136, 0xe137, 0xe138, 0xe139,
+ 0xe13a, 0xe13b, 0xe13c, 0xe13d,
+ 0xe13e, 0xe13f, 0xe140, 0xe141,
+ // F0d0
+ 0x2220, 0xe142, 0x00ae, 0x00a9,
+ 0xe143, 0xe144, 0xe145, 0xe146,
+ 0xe147, 0xe148, 0xe149, 0xe14a,
+ 0xe14b, 0x21d1, 0xe14c, 0x21d3,
+ // F0e0
+ 0x25ca, 0xe14d, 0xe14e, 0xe14f,
+ 0xe150, 0xe151, 0xe152, 0xe153,
+ 0xe154, 0xe155, 0xe156, 0xe157,
+ 0xe158, 0xe159, 0xe15a, 0xe15b,
+ // F0f0
+ 0, 0xe15c, 0xe15d, 0xe15e,
+ 0xe15f, 0xe160, 0xe161, 0xe162,
+ 0xe163, 0xe164, 0xe165, 0xe166,
+ 0xe167, 0xe168, 0xe169, 0,
+};
+
+// -----------------------------------------------------------------------
+
+static const sal_Unicode aMonotypeSortsTab[224] =
+{
+ // F020
+ 0x0020, 0x2701, 0xe200, 0x2703,
+ 0x2704, 0xe201, 0x2706, 0xe202,
+ 0xe203, 0xe203, 0xe204, 0xe205,
+ 0x270c, 0xe206, 0xe207, 0xe208,
+ // F030
+ 0x2710, 0x2711, 0x2712, 0xe209,
+ 0xe20a, 0x2715, 0x2716, 0xe20b,
+ 0xe20c, 0xe20d, 0xe20e, 0xe20f,
+ 0xe210, 0x271d, 0x271e, 0x271f,
+ // F040
+ 0x2720, 0xe211, 0xe212, 0xe213,
+ 0xe214, 0xe215, 0x2726, 0x2727,
+ 0x2605, 0x2729, 0x272a, 0xe216,
+ 0xe217, 0xe218, 0xe219, 0xe21a,
+ // F050
+ 0xe21b, 0xe21c, 0x2732, 0xe21d,
+ 0xe21e, 0xe21f, 0xe220, 0xe221,
+ 0xe222, 0xe223, 0x273a, 0x273b,
+ 0x273c, 0x273d, 0x273e, 0xe224,
+ // F060
+ 0x2740, 0x2741, 0x2742, 0x2743,
+ 0xe225, 0x2745, 0x2746, 0x2747,
+ 0x2748, 0x2749, 0x274a, 0x274b,
+ 0xe226, 0xe227, 0xe228, 0xe229,
+ // F070
+ 0xe22a, 0xe22b, 0xe22c, 0x25b2,
+ 0x25bc, 0xe22d, 0xe22e, 0xe22f,
+ 0x2758, 0xe230, 0x275a, 0x275b,
+ 0x275c, 0x275d, 0x275e, 0,
+ // F080
+ 0xe231, 0xe232, 0xe233, 0xe234,
+ 0xe235, 0xe236, 0xe237, 0xe238,
+ 0xe239, 0xe23a, 0xe23b, 0xe23c,
+ 0xe23d, 0xe23e, 0, 0,
+ // F090
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0a0
+ 0, 0xe23f, 0xe240, 0x2763,
+ 0x2764, 0x2765, 0x2766, 0x2767,
+ 0xe241, 0xe242, 0xe243, 0xe244,
+ 0x2460, 0x2461, 0x2462, 0x2463,
+ // F0b0
+ 0x2464, 0x2465, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0x2776, 0x2777,
+ 0x2778, 0x2779, 0x277a, 0x277b,
+ 0x277c, 0x277d, 0x277e, 0x277f,
+ // F0c0
+ 0xe245, 0xe246, 0xe247, 0xe248,
+ 0xe249, 0xe24a, 0xe24b, 0xe24c,
+ 0xe24d, 0xe24e, 0xe24f, 0xe250,
+ 0xe251, 0xe252, 0xe253, 0xe254,
+ // F0d0
+ 0xe255, 0xe256, 0xe257, 0xe258,
+ 0xe259, 0xe25a, 0xe25b, 0xe25c,
+ 0xe25d, 0x2799, 0xe25e, 0x279b,
+ 0x279c, 0x279d, 0x279e, 0x279f,
+ // F0e0
+ 0x27a0, 0x27a1, 0xe25f, 0x27a3,
+ 0x27a4, 0x27a5, 0x27a6, 0x27a7,
+ 0x27a8, 0x27a9, 0x27aa, 0x27ab,
+ 0x27ac, 0x27ad, 0x27ae, 0x27af,
+ // F0f0
+ 0, 0x27b1, 0xe260, 0x27b3,
+ 0x27b4, 0x27b5, 0x27b6, 0x27b7,
+ 0xe261, 0x27b9, 0x27ba, 0x27bb,
+ 0x27bc, 0x27bd, 0x27be, 0,
+};
+
+// -----------------------------------------------------------------------
+
+/*
+static const sal_Unicode aMonotypeSorts2Tab[224] =
+{
+//TODO:
+ // F020
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F030
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F040
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F050
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F060
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F070
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F080
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F090
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0a0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0b0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0c0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0d0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0e0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0f0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+*/
+
+static const sal_Unicode aMTExtraTab[224] =
+{
+ // F020
+ 0x0020, 0, 0, 0xE095,
+ 0xE091, 0xE096, 0x02D9, 0,
+ 0xE093, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F030
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0x25C1, 0, 0x25B7, 0,
+ // F040
+ 0, 0, 0x2210, 0x019b,
+ 0, 0, 0, 0,
+ 0, 0x2229, 0, 0xE08B,
+ 0x22EF, 0x22EE, 0x22F0, 0x22F1,
+ // F050
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F060
+ 0xE095, 0, 0xE25C, 0xE4BA,
+ 0, 0, 0x210F, 0,
+ 0, 0, 0, 0,
+ 0x2113, 0x2213, 0, 0x00B0,
+ // F070
+ 0, 0, 0xE098, 0,
+ 0, 0xE097, 0, 0,
+ 0, 0, 0, 0xE081,
+ 0, 0xE082, 0, 0,
+ // F080
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F090
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0a0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0b0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0c0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0d0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0e0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ // F0f0
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+
+//=======================================================================
+
+static sal_Unicode ImplStarSymbolToStarBats( sal_Unicode c )
+{
+ switch ( c )
+ {
+ case 0x00A2: c = 0xF0E0; break;
+ case 0x00A4: c = 0xF0E1; break;
+ case 0x00A5: c = 0xF0E2; break;
+ case 0x00A7: c = 0xF0A7; break;
+ case 0x00AB: c = 0xF0AB; break;
+ case 0x00B6: c = 0xF0DE; break;
+ case 0x00BB: c = 0xF0BB; break;
+
+ case 0x0152: c = 0xF08C; break;
+ case 0x0153: c = 0xF09C; break;
+ case 0x0160: c = 0xF08A; break;
+ case 0x0161: c = 0xF09A; break;
+ case 0x0178: c = 0xF09F; break;
+ case 0x017D: c = 0xF08E; break;
+ case 0x017E: c = 0xF09E; break;
+
+ case 0x0192: c = 0xF083; break;
+ case 0x02C6: c = 0xF088; break;
+ case 0x02DC: c = 0xF098; break;
+ case 0x2013: c = 0xF096; break;
+ case 0x2014: c = 0xF097; break;
+ case 0x2018: c = 0xF091; break;
+
+ case 0x2019: c = 0xF092; break;
+ case 0x201A: c = 0xF082; break;
+ case 0x201C: c = 0xF093; break;
+ case 0x201D: c = 0xF094; break;
+ case 0x201E: c = 0xF084; break;
+ case 0x2020: c = 0xF086; break;
+
+ case 0x2021: c = 0xF087; break;
+ case 0x2022: c = 0xF095; break;
+ case 0x2026: c = 0xF085; break;
+ case 0x2030: c = 0xF089; break;
+ case 0x2039: c = 0xF08B; break;
+ case 0x203A: c = 0xF09B; break;
+
+ case 0x20A1: c = 0xF0E4; break;
+ case 0x20A2: c = 0xF0E5; break;
+ case 0x20A3: c = 0xF0E6; break;
+ case 0x20A4: c = 0xF0E7; break;
+ case 0x20A8: c = 0xF0EA; break;
+ case 0x20A9: c = 0xF0E8; break;
+ case 0x20AB: c = 0xF0E9; break;
+ case 0x20AC: c = 0xF080; break;
+
+ case 0x2122: c = 0xF099; break;
+ case 0x2190: c = 0xF0B7; break;
+ case 0x2191: c = 0xF0B8; break;
+ case 0x2192: c = 0xF0B5; break;
+ case 0x2193: c = 0xF0B6; break;
+ case 0x2194: c = 0xF0D8; break;
+ case 0x2195: c = 0xF0D9; break;
+
+ case 0x21E4: c = 0xF0B4; break;
+ case 0x21E5: c = 0xF0B3; break;
+ case 0x21E6: c = 0xF0A4; break;
+ case 0x21E7: c = 0xF0B2; break;
+ case 0x21E8: c = 0xF0AF; break;
+ case 0x21E9: c = 0xF0A3; break;
+
+ case 0x25A0: c = 0xF024; break;
+ case 0x25A1: c = 0xF025; break;
+ case 0x25B4: c = 0xF0C5; break;
+ case 0x25B5: c = 0xF0C7; break;
+ case 0x25BE: c = 0xF0C4; break;
+ case 0x25BF: c = 0xF0C6; break;
+ case 0x25C6: c = 0xF043; break;
+ case 0x25CF: c = 0xF022; break;
+ case 0x25D7: c = 0xF0D0; break;
+
+ case 0x260E: c = 0xF074; break;
+ case 0x2611: c = 0xF034; break;
+ case 0x2612: c = 0xF033; break;
+ case 0x261B: c = 0xF036; break;
+ case 0x261E: c = 0xF07D; break;
+ case 0x2639: c = 0xF0AD; break;
+ case 0x263A: c = 0xF021; break;
+
+ case 0x2702: c = 0xF0CB; break;
+ case 0x2708: c = 0xF0CC; break;
+ case 0x270D: c = 0xF07E; break;
+ case 0x270E: c = 0xF038; break;
+
+ case 0x2713: c = 0xF039; break;
+ case 0x2714: c = 0xF03A; break;
+ case 0x2717: c = 0xF04F; break;
+ case 0x2718: c = 0xF050; break;
+ case 0x2719: c = 0xF051; break;
+ case 0x271A: c = 0xF052; break;
+ case 0x271B: c = 0xF053; break;
+ case 0x271C: c = 0xF054; break;
+
+ case 0x2721: c = 0xF0CD; break;
+ case 0x2722: c = 0xF044; break;
+ case 0x2723: c = 0xF045; break;
+ case 0x2724: c = 0xF046; break;
+ case 0x2725: c = 0xF047; break;
+ case 0x272B: c = 0xF055; break;
+ case 0x272C: c = 0xF056; break;
+ case 0x272D: c = 0xF057; break;
+ case 0x272E: c = 0xF058; break;
+ case 0x272F: c = 0xF059; break;
+
+ case 0x2730: c = 0xF05A; break;
+ case 0x2733: c = 0xF048; break;
+ case 0x2734: c = 0xF049; break;
+ case 0x2735: c = 0xF04A; break;
+ case 0x2736: c = 0xF04B; break;
+ case 0x2737: c = 0xF04C; break;
+ case 0x2738: c = 0xF04D; break;
+ case 0x2739: c = 0xF04E; break;
+ case 0x273F: c = 0xF0CE; break;
+
+ case 0x2744: c = 0xF0CF; break;
+ case 0x274D: c = 0xF023; break;
+ case 0x274F: c = 0xF03E; break;
+ case 0x2750: c = 0xF03F; break;
+ case 0x2751: c = 0xF027; break;
+ case 0x2752: c = 0xF028; break;
+ case 0x2756: c = 0xF02C; break;
+ case 0x2759: c = 0xF0D1; break;
+ case 0x2762: c = 0xF0D4; break;
+
+ case 0x2780: c = 0xF068; break;
+ case 0x2781: c = 0xF069; break;
+ case 0x2782: c = 0xF06A; break;
+ case 0x2783: c = 0xF06B; break;
+ case 0x2784: c = 0xF06C; break;
+ case 0x2785: c = 0xF06D; break;
+ case 0x2786: c = 0xF06E; break;
+ case 0x2787: c = 0xF06F; break;
+ case 0x2788: c = 0xF070; break;
+ case 0x2789: c = 0xF071; break;
+ case 0x278A: c = 0xF05D; break;
+ case 0x278B: c = 0xF05E; break;
+ case 0x278C: c = 0xF05F; break;
+ case 0x278D: c = 0xF060; break;
+ case 0x278E: c = 0xF061; break;
+ case 0x278F: c = 0xF062; break;
+
+ case 0x2790: c = 0xF063; break;
+ case 0x2791: c = 0xF064; break;
+ case 0x2792: c = 0xF065; break;
+ case 0x2793: c = 0xF066; break;
+ case 0x2794: c = 0xF031; break;
+ case 0x2798: c = 0xF0DA; break;
+ case 0x279A: c = 0xF0DB; break;
+
+ case 0x27A2: c = 0xF02F; break;
+ case 0x27B2: c = 0xF035; break;
+ case 0x27B8: c = 0xF0DC; break;
+
+ case 0xE000: c = 0xF000+38; break;
+ case 0xE001: c = 0xF000+41; break;
+ case 0xE002: c = 0xF000+42; break;
+ case 0xE003: c = 0xF000+43; break;
+ case 0xE004: c = 0xF000+45; break;
+ case 0xE005: c = 0xF000+46; break;
+ case 0xE006: c = 0xF000+48; break;
+ case 0xE007: c = 0xF000+57; break;
+
+ case 0xE008: c = 0xF000+59; break;
+ case 0xE009: c = 0xF000+60; break;
+ case 0xE00a: c = 0xF000+61; break;
+ case 0xE00b: c = 0xF000+64; break;
+ case 0xE00c: c = 0xF000+65; break;
+ case 0xE00d: c = 0xF000+66; break;
+ case 0xE00e: c = 0xF000+67; break;
+ case 0xE00f: c = 0xF000+92; break;
+
+ case 0xE010: c = 0xF000+103; break;
+ case 0xE011: c = 0xF000+114; break;
+ case 0xE012: c = 0xF000+115; break;
+ case 0xE013: c = 0xF000+117; break;
+ case 0xE014: c = 0xF000+118; break;
+ case 0xE015: c = 0xF000+119; break;
+ case 0xE016: c = 0xF000+120; break;
+ case 0xE017: c = 0xF000+121; break;
+
+ case 0xE018: c = 0xF000+122; break;
+ case 0xE019: c = 0xF000+123; break;
+ case 0xE01a: c = 0xF000+124; break;
+ case 0xE01b: c = 0xF000+126; break;
+ case 0xE01c: c = 0xF000+136; break;
+ case 0xE01d: c = 0xF000+155; break;
+ case 0xE01e: c = 0xF000+165; break;
+ case 0xE01f: c = 0xF000+166; break;
+
+ case 0xE020: c = 0xF000+168; break;
+ case 0xE021: c = 0xF000+169; break;
+ case 0xE022: c = 0xF000+170; break;
+ case 0xE023: c = 0xF000+172; break;
+ case 0xE024: c = 0xF000+174; break;
+ case 0xE025: c = 0xF000+175; break;
+ case 0xE026: c = 0xF000+176; break;
+ case 0xE027: c = 0xF000+177; break;
+
+ case 0xE028: c = 0xF000+178; break;
+ case 0xE029: c = 0xF000+185; break;
+ case 0xE02a: c = 0xF000+186; break;
+ case 0xE02b: c = 0xF000+188; break;
+ case 0xE02c: c = 0xF000+189; break;
+ case 0xE02d: c = 0xF000+190; break;
+ case 0xE02e: c = 0xF000+191; break;
+ case 0xE02f: c = 0xF000+192; break;
+
+ case 0xE030: c = 0xF000+193; break;
+ case 0xE031: c = 0xF000+194; break;
+ case 0xE032: c = 0xF000+195; break;
+ case 0xE033: c = 0xF000+200; break;
+ case 0xE034: c = 0xF000+201; break;
+ case 0xE035: c = 0xF000+202; break;
+ case 0xE036: c = 0xF000+210; break;
+ case 0xE037: c = 0xF000+211; break;
+
+ case 0xE038: c = 0xF000+227; break;
+ case 0xE039: c = 0xF000+235; break;
+ case 0xE03a: c = 0xF000+255; break;
+
+ default: c = 0; break;
+ }
+
+ return c;
+}
+
+enum SymbolFont
+{
+ Symbol=1, Wingdings=2, MonotypeSorts=4, Webdings=8, Wingdings2=16,
+ Wingdings3=32, MTExtra=64, TimesNewRoman=128
+};
+
+const char *aSymbolNames[] =
+{
+ "Symbol", "Wingdings", "Monotype Sorts", "Webdings", "Wingdings 2",
+ "Wingdings 3", "MT Extra", "Times New Roman"
+};
+
+struct SymbolEntry
+{
+ sal_uInt8 cIndex;
+ enum SymbolFont eFont;
+};
+
+class StarSymbolToMSMultiFontImpl : public StarSymbolToMSMultiFont
+{
+private:
+ ::std::multimap<sal_Unicode, SymbolEntry> maMagicMap;
+public:
+ StarSymbolToMSMultiFontImpl(bool bPerfectOnly);
+ String ConvertChar(sal_Unicode &rChar);
+ String ConvertString(String &rString, xub_StrLen& rIndex);
+};
+
+struct ExtraTable { sal_Unicode cStar; sal_uInt8 cMS;};
+
+ExtraTable aWingDingsExtraTab[] =
+{
+ {0x25cf, 0x6C}, {0x2714, 0xFC}, {0x2717, 0xFB}, {0x2794, 0xE8},
+ {0x27a2, 0xD8}, {0xe000, 0x6F}, {0xe001, 0x73}, {0xe002, 0x74},
+ {0xe003, 0x75}, {0xe004, 0x77}, {0xe005, 0xA6}, {0xe006, 0xE0},
+ {0xe007, 0xFC}, {0xe008, 0x6C}, {0xe009, 0x6D}, {0xe00a, 0x6E},
+ {0xe00b, 0x72}, {0xe00c, 0x75}, {0xe00d, 0x76}, {0xe00e, 0x74},
+ {0xe00f, 0x8B}, {0xe010, 0x80}, {0xe011, 0x2B}, {0xe012, 0x3A},
+ {0xe013, 0x5D}, {0xe014, 0x29}, {0xe015, 0x3A}, {0xe016, 0x3C},
+ {0xe017, 0x38}, {0xe018, 0x3A}, {0xe019, 0x2A}, {0xe01a, 0x2B},
+ {0xe01b, 0x3F}, {0xe01c, 0x9F}, {0xe01d, 0x80}, {0xe01e, 0x8B},
+ {0xe023, 0x4A}, {0xe025, 0xF0}, {0xe026, 0xF2}, {0xe027, 0xEF},
+ {0xe028, 0xF1}, {0xe029, 0x52}, {0xe02a, 0x29}, {0xe02b, 0xE0},
+ {0xe02c, 0xE2}, {0xe02d, 0xDF}, {0xe02e, 0xE1}, {0xe02f, 0xAC},
+ {0xe030, 0xAD}, {0xe031, 0xAE}, {0xe032, 0x7C}, {0xe033, 0x43},
+ {0xe034, 0x4D}, {0xe0aa, 0x71}, {0xe422, 0x44}
+};
+
+ExtraTable aSymbolExtraTab2[] =
+{
+ {0x0020, 0x20}, {0x00A0, 0x20}, {0x0021, 0x21}, {0x2200, 0x22},
+ {0x0023, 0x23}, {0x2203, 0x24}, {0x0025, 0x25}, {0x0026, 0x26},
+ {0x220B, 0x27}, {0x0028, 0x28}, {0x0029, 0x29}, {0x2217, 0x2A},
+ {0x002B, 0x2B}, {0x002C, 0x2C}, {0x2212, 0x2D}, {0x002E, 0x2E},
+ {0x002F, 0x2F}, {0x003A, 0x3A}, {0x003B, 0x3B}, {0x003C, 0x3C},
+ {0x003D, 0x3D}, {0x003E, 0x3E}, {0x2245, 0x40}, {0x2206, 0x44},
+ {0x2126, 0x57}, {0x005B, 0x5B}, {0x005D, 0x5D}, {0x22A5, 0x5E},
+ {0x03C6, 0x66}, {0x03D5, 0x6A}, {0x00B5, 0x6D}, {0x007B, 0x7B},
+ {0x007C, 0x7C}, {0x007D, 0x7D}, {0x223C, 0x7E}, {0x20AC, 0xA0},
+ {0x2032, 0xA2}, {0x2264, 0xA3}, {0x2044, 0xA4}, {0x221E, 0xA5},
+ {0x0192, 0xA6}, {0x2663, 0xA7}, {0x2665, 0xA9}, {0x2660, 0xAA},
+ {0x2194, 0xAB}, {0x2190, 0xAC}, {0x2191, 0xAD}, {0x2192, 0xAE},
+ {0x2193, 0xAF}, {0x00B0, 0xB0}, {0x00B1, 0xB1}, {0x2265, 0xB3},
+ {0x00D7, 0xB4}, {0x221D, 0xB5}, {0x2202, 0xB6}, {0x2022, 0xB7},
+ {0x00F7, 0xB8}, {0x2260, 0xB9}, {0x2261, 0xBA}, {0x2248, 0xBB},
+ {0x2026, 0xBC}, {0x21B5, 0xBF}, {0x2135, 0xC0}, {0x2111, 0xC1},
+ {0x211C, 0xC2}, {0x2118, 0xC3}, {0x2297, 0xC4}, {0x2295, 0xC5},
+ {0x2205, 0xC6}, {0x2229, 0xC7}, {0x222A, 0xC8}, {0x2283, 0xC9},
+ {0x2287, 0xCA}, {0x2284, 0xCB}, {0x2282, 0xCC}, {0x2286, 0xCD},
+ {0x2208, 0xCE}, {0x2209, 0xCF}, {0x2207, 0xD1}, {0x220F, 0xD5},
+ {0x221A, 0xD6}, {0x22C5, 0xD7}, {0x00AC, 0xD8}, {0x2227, 0xD9},
+ {0x2228, 0xDA}, {0x21D4, 0xDB}, {0x21D0, 0xDC}, {0x21D2, 0xDE},
+ {0x2329, 0xE1}, {0x2211, 0xE5}, {0x232A, 0xF1}, {0x222B, 0xF2},
+ {0x2320, 0xF3}, {0x2321, 0xF5}, {0x2013, 0x2D}
+};
+
+ExtraTable aSymbolExtraTab[] =
+{
+ {0xe021, 0xD3}, {0xe024, 0xD2}, {0xe035, 0x20}, {0xe036, 0x28},
+ {0xe037, 0x29}, {0xe039, 0x20}, {0xe083, 0x2B}, {0xe084, 0x3C},
+ {0xe085, 0x3E}, {0xe086, 0xA3}, {0xe087, 0xB3}, {0xe089, 0xCE},
+ {0xe08a, 0xA6}, {0xe08c, 0xAE}, {0xe08d, 0xD6}, {0xe08e, 0xD6},
+ {0xe08f, 0xD6}, {0xe094, 0xA2}, {0xe09e, 0x28}, {0xe09f, 0x29},
+ {0xe0a0, 0xD0}, {0xe0a6, 0xA2}, {0xe0a7, 0x7C}, {0xe0a8, 0x2F},
+ {0xe0ab, 0x7C}, {0xe0ac, 0x47}, {0xe0ad, 0x44}, {0xe0ae, 0x51},
+ {0xe0af, 0x4C}, {0xe0b0, 0x58}, {0xe0b1, 0x50}, {0xe0b2, 0x53},
+ {0xe0b3, 0x55}, {0xe0b4, 0x46}, {0xe0b5, 0x59}, {0xe0b6, 0x57},
+ {0xe0b7, 0x61}, {0xe0b8, 0x62}, {0xe0b9, 0x67}, {0xe0ba, 0x64},
+ {0xe0bb, 0x65}, {0xe0bc, 0x7A}, {0xe0bd, 0x68}, {0xe0be, 0x71},
+ {0xe0bf, 0x69}, {0xe0c0, 0x6B}, {0xe0c1, 0x6C}, {0xe0c2, 0x6D},
+ {0xe0c3, 0x6E}, {0xe0c4, 0x78}, {0xe0c5, 0x6F}, {0xe0c6, 0x70},
+ {0xe0c7, 0x72}, {0xe0c8, 0x73}, {0xe0c9, 0x74}, {0xe0ca, 0x75},
+ {0xe0cb, 0x66}, {0xe0cc, 0x63}, {0xe0cd, 0x79}, {0xe0ce, 0x77},
+ {0xe0cf, 0x65}, {0xe0d0, 0x4A}, {0xe0d1, 0x76}, {0xe0d3, 0x56},
+ {0xe0d4, 0x6A}, {0xe0d5, 0xB6}, {0xe0d6, 0x69}, {0xe0db, 0xAC},
+ {0xe0dc, 0xAD}, {0xe0dd, 0xAF}
+};
+
+ExtraTable aTNRExtraTab[] =
+{
+ {0xe021, 0xA9},
+ {0xe022, 0x40},
+ {0xe024, 0xAE},
+ {0xe035, 0x20},
+ {0xe036, '('},
+ {0xe037, ')'},
+ {0xe039, 0x20},
+ {0xe03a, 0x80},
+ {0xe080, 0x89},
+ {0xe083, '+'},
+ {0xe084, '<'},
+ {0xe085, '>'},
+ {0xe0a9, '\\'}
+};
+
+StarSymbolToMSMultiFontImpl::StarSymbolToMSMultiFontImpl(bool bPerfectOnly)
+{
+ struct ConvertTable
+ {
+ enum SymbolFont meFont;
+ const sal_Unicode* pTab;
+ };
+
+ //In order of preference
+ const ConvertTable aConservativeTable[] =
+ {
+ {Symbol, aAdobeSymbolTab},
+ {Wingdings, aWingDingsTab},
+ {MonotypeSorts, aMonotypeSortsTab},
+ {Webdings, aWebDingsTab},
+ {Wingdings2, aWingDings2Tab},
+ {Wingdings3, aWingDings3Tab},
+ {MTExtra, aMTExtraTab}
+ };
+
+ struct ExtendedConvertTable
+ {
+ enum SymbolFont meFont;
+ const ExtraTable *mpTable;
+ size_t mnSize;
+ ExtendedConvertTable(SymbolFont eFont, const ExtraTable *pTable,
+ size_t nSize)
+ : meFont(eFont), mpTable(pTable), mnSize(nSize) {}
+ };
+
+ //Reverse map from a given starsymbol char to exact matches in ms symbol
+ //fonts.
+ int nEntries = sizeof(aConservativeTable) / sizeof(aConservativeTable[0]);
+ int i;
+ for (i = 0; i < nEntries; ++i)
+ {
+ const ConvertTable& r = aConservativeTable[i];
+ SymbolEntry aEntry;
+ aEntry.eFont = r.meFont;
+ for (aEntry.cIndex = 0xFF; aEntry.cIndex >= 0x20; --aEntry.cIndex)
+ {
+ if (sal_Unicode cChar = r.pTab[aEntry.cIndex-0x20])
+ maMagicMap.insert(
+ ::std::multimap<sal_Unicode, SymbolEntry>::value_type(
+ cChar, aEntry));
+ }
+ }
+
+ //In order of preference
+ const ExtendedConvertTable aAgressiveTable[] =
+ {
+ ExtendedConvertTable(Symbol, aSymbolExtraTab2,
+ sizeof(aSymbolExtraTab2)),
+ ExtendedConvertTable(Symbol, aSymbolExtraTab,
+ sizeof(aSymbolExtraTab)),
+ ExtendedConvertTable(Wingdings, aWingDingsExtraTab,
+ sizeof(aWingDingsExtraTab)),
+ ExtendedConvertTable(TimesNewRoman, aTNRExtraTab,
+ sizeof(aTNRExtraTab))
+ };
+
+ //Allow extra conversions that are not perfect, but "good enough"
+ if (!bPerfectOnly)
+ nEntries = sizeof(aAgressiveTable) / sizeof(aAgressiveTable[0]);
+ else
+ nEntries = 1;
+
+ for (i = 0; i < nEntries; ++i)
+ {
+ const ExtendedConvertTable& r = aAgressiveTable[i];
+ SymbolEntry aEntry;
+ aEntry.eFont = r.meFont;
+ for (int j = r.mnSize / sizeof(r.mpTable[0]); j >=0; --j)
+ {
+ aEntry.cIndex = r.mpTable[j].cMS;
+ maMagicMap.insert(
+ ::std::multimap<sal_Unicode, SymbolEntry>::value_type(
+ r.mpTable[j].cStar, aEntry));
+ }
+ }
+}
+
+const char *SymbolFontToString(int nResult)
+{
+ const char **ppName = aSymbolNames;
+ int nI = Symbol;
+ while (nI <= nResult)
+ {
+ if (!(nI & nResult))
+ nI = nI << 1;
+ else
+ break;
+ ppName++;
+ }
+ return *ppName;
+}
+
+String StarSymbolToMSMultiFontImpl::ConvertChar(sal_Unicode &rChar)
+{
+ String sRet;
+
+ ::std::multimap<sal_Unicode, SymbolEntry>::const_iterator aResult =
+ maMagicMap.find(rChar);
+
+ if (aResult != maMagicMap.end())
+ {
+ const SymbolEntry &rEntry = (*aResult).second;
+ sRet.AssignAscii(SymbolFontToString(rEntry.eFont));
+ rChar = rEntry.cIndex;
+ }
+
+ return sRet;
+}
+
+String StarSymbolToMSMultiFontImpl::ConvertString(String &rString,
+ xub_StrLen& rIndex)
+{
+ typedef ::std::multimap<sal_Unicode, SymbolEntry>::iterator MI;
+ typedef ::std::pair<MI, MI> Result;
+
+ String sRet;
+
+ xub_StrLen nLen = rString.Len();
+ if (rIndex >= nLen)
+ return sRet;
+
+ int nTotal = 0, nResult = 0;
+ ::std::vector<Result> aPossibilities;
+ aPossibilities.reserve(nLen - rIndex);
+ xub_StrLen nStart = rIndex;
+ do
+ {
+ Result aResult = maMagicMap.equal_range(rString.GetChar(rIndex));
+ int nBitfield = 0;
+ for (MI aIndex = aResult.first; aIndex != aResult.second; ++aIndex)
+ nBitfield |= aIndex->second.eFont;
+
+ if (!nTotal)
+ nTotal = nBitfield;
+ else
+ {
+ if (nTotal != nBitfield) //Allow a series of failures
+ {
+ nTotal &= nBitfield;
+ if (!nTotal)
+ break;
+ }
+ }
+ nResult = nTotal;
+ if (nResult) //Don't bother storing a series of failures
+ aPossibilities.push_back(aResult);
+ ++rIndex;
+ }while(rIndex < nLen);
+
+ if (nResult)
+ {
+ int nI = Symbol;
+ while (nI <= nResult)
+ {
+ if (!(nI & nResult))
+ nI = nI << 1;
+ else
+ break;
+ }
+ sRet.AssignAscii(SymbolFontToString(nI));
+
+ xub_StrLen nSize = sal::static_int_cast<xub_StrLen>(aPossibilities.size());
+ for(xub_StrLen nPos = 0; nPos < nSize; ++nPos)
+ {
+ const Result &rResult = aPossibilities[nPos];
+
+ for (MI aIndex = rResult.first; aIndex != rResult.second; ++aIndex)
+ {
+ if (aIndex->second.eFont == nI)
+ {
+ rString.SetChar(nPos+nStart, aIndex->second.cIndex);
+ break;
+ }
+ }
+ }
+ }
+
+ return sRet;
+}
+
+StarSymbolToMSMultiFont *CreateStarSymbolToMSMultiFont(bool bPerfectOnly)
+{
+ return new StarSymbolToMSMultiFontImpl(bPerfectOnly);
+}
+
+//=======================================================================
+
+sal_Unicode ConvertChar::RecodeChar( sal_Unicode cChar ) const
+{
+ sal_Unicode cRetVal = 0;
+ if( mpCvtFunc )
+ {
+ // use a conversion function for recoding
+ cRetVal = mpCvtFunc( cChar );
+ }
+ else
+ {
+ // use a conversion table for recoding
+ sal_Unicode cIndex = cChar;
+ // allow symbol aliasing
+ if( cIndex & 0xFF00 )
+ cIndex -= 0xF000;
+ // recode the symbol
+ if( cIndex>=0x0020 && cIndex<=0x00FF )
+ cRetVal = mpCvtTab[ cIndex - 0x0020 ];
+ }
+
+ return cRetVal ? cRetVal : cChar;
+}
+
+// -----------------------------------------------------------------------
+
+// recode the string assuming the character codes are symbol codes
+// from an traditional symbol font (i.e. U+F020..U+F0FF)
+void ConvertChar::RecodeString( String& rStr, xub_StrLen nIndex, xub_StrLen nLen ) const
+{
+ ULONG nLastIndex = (ULONG)nIndex + nLen;
+ if( nLastIndex > rStr.Len() )
+ nLastIndex = rStr.Len();
+
+ for(; nIndex < nLastIndex; ++nIndex )
+ {
+ sal_Unicode cOrig = rStr.GetChar( nIndex );
+ // only recode symbols and their U+00xx aliases
+ if( ((cOrig < 0x0020) || (cOrig > 0x00FF))
+ && ((cOrig < 0xF020) || (cOrig > 0xF0FF)) )
+ continue;
+
+ // recode a symbol
+ sal_Unicode cNew = RecodeChar( cOrig );
+ if( cOrig != cNew )
+ rStr.SetChar( nIndex, cNew );
+ }
+}
+
+//=======================================================================
+
+struct RecodeTable { const char* pOrgName; ConvertChar aCvt;};
+
+static RecodeTable aRecodeTable[] =
+{
+ // the first two entries must be StarMath and StarBats; do not reorder!
+ // reason: fgrep for FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS
+ {"starbats", {aStarBatsTab, "StarSymbol", NULL}},
+ {"starmath", {aStarMathTab, "StarSymbol", NULL}},
+
+ {"symbol", {aAdobeSymbolTab, "StarSymbol", NULL}},
+ {"standardsymbols", {aAdobeSymbolTab, "StarSymbol", NULL}},
+ {"standardsymbolsl",{aAdobeSymbolTab, "StarSymbol", NULL}},
+
+ {"monotypesorts", {aMonotypeSortsTab, "StarSymbol", NULL}},
+// {"monotypesorts2", {aMonotypeSorts2Tab, "StarSymbol", NULL}}
+ {"zapfdingbats", {aMonotypeSortsTab, "StarSymbol", NULL}}, //ZapfDingbats=MonotypeSorts-X?
+ {"itczapfdingbats", {aMonotypeSortsTab, "StarSymbol", NULL}},
+ {"dingbats", {aMonotypeSortsTab, "StarSymbol", NULL}},
+
+ {"webdings", {aWebDingsTab, "StarSymbol", NULL}},
+ {"wingdings", {aWingDingsTab, "StarSymbol", NULL}},
+ {"wingdings2", {aWingDings2Tab, "StarSymbol", NULL}},
+ {"wingdings3", {aWingDings3Tab, "StarSymbol", NULL}},
+ {"mtextra", {aMTExtraTab, "StarSymbol", NULL}}
+};
+
+static ConvertChar aImplStarSymbolCvt = { NULL, "StarBats", ImplStarSymbolToStarBats };
+
+// -----------------------------------------------------------------------
+
+const ConvertChar* ConvertChar::GetRecodeData( const String& rOrgFontName, const String& rMapFontName )
+{
+ const ConvertChar* pCvt = NULL;
+ String aOrgName( rOrgFontName );
+ GetEnglishSearchFontName( aOrgName );
+ String aMapName( rMapFontName );
+ GetEnglishSearchFontName( aMapName );
+
+ if( aMapName.EqualsAscii( "starsymbol" )
+ || aMapName.EqualsAscii( "opensymbol" ) )
+ {
+ int nEntries = sizeof(aRecodeTable) / sizeof(aRecodeTable[0]);
+ for( int i = 0; i < nEntries; ++i)
+ {
+ RecodeTable& r = aRecodeTable[i];
+ if( aOrgName.EqualsAscii( r.pOrgName ) )
+ { pCvt = &r.aCvt; break; }
+ }
+ }
+ else if( aMapName.EqualsAscii( "starbats" ) )
+ {
+ if( aOrgName.EqualsAscii( "starsymbol" ) )
+ pCvt = &aImplStarSymbolCvt;
+ else if( aOrgName.EqualsAscii( "opensymbol" ) )
+ pCvt = &aImplStarSymbolCvt;
+ }
+
+ return pCvt;
+}
+
+//=======================================================================
+
+FontToSubsFontConverter CreateFontToSubsFontConverter(
+ const String& rOrgName, ULONG nFlags )
+{
+ const ConvertChar* pCvt = NULL;
+
+ String aName = rOrgName;
+ GetEnglishSearchFontName( aName );
+
+ if ( nFlags & FONTTOSUBSFONT_IMPORT )
+ {
+ int nEntries = sizeof(aRecodeTable) / sizeof(aRecodeTable[0]);
+ if ( nFlags & FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS ) // only StarMath+StarBats
+ nEntries = 2;
+ for( int i = 0; i < nEntries; ++i )
+ {
+ RecodeTable& r = aRecodeTable[i];
+ if( aName.EqualsAscii( r.pOrgName ) )
+ { pCvt = &r.aCvt; break; }
+ }
+ }
+ else
+ {
+ // TODO: FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS
+ if( aName.EqualsAscii( "starsymbol" ) ) pCvt = &aImplStarSymbolCvt;
+ else if( aName.EqualsAscii( "opensymbol" ) ) pCvt = &aImplStarSymbolCvt;
+ }
+
+ return (FontToSubsFontConverter)pCvt;
+}
+
+// -----------------------------------------------------------------------
+
+void DestroyFontToSubsFontConverter( FontToSubsFontConverter )
+{
+ // nothing to do for now, because we use static ImplCvtChars
+}
+
+// -----------------------------------------------------------------------
+
+sal_Unicode ConvertFontToSubsFontChar(
+ FontToSubsFontConverter hConverter, sal_Unicode cChar )
+{
+ if ( hConverter )
+ return ((ConvertChar*)hConverter)->RecodeChar( cChar );
+ else
+ return cChar;
+}
+
+// -----------------------------------------------------------------------
+
+String GetFontToSubsFontName( FontToSubsFontConverter hConverter )
+{
+ if ( !hConverter )
+ return String();
+
+ const char* pName = ((ConvertChar*)hConverter)->mpSubsFontName;
+ return String::CreateFromAscii( pName );
+}
+
diff --git a/unotools/source/misc/fontdefs.cxx b/unotools/source/misc/fontdefs.cxx
new file mode 100644
index 000000000000..15e67c44f001
--- /dev/null
+++ b/unotools/source/misc/fontdefs.cxx
@@ -0,0 +1,596 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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_unotools.hxx"
+#include <unotools/fontdefs.hxx>
+#include <unotools/fontcfg.hxx>
+#include <hash_map>
+
+struct ImplLocalizedFontName
+{
+ const char* mpEnglishName;
+ const sal_Unicode* mpLocalizedNames;
+};
+
+static sal_Unicode const aBatang[] = { 0xBC14, 0xD0D5, 0, 0 };
+static sal_Unicode const aBatangChe[] = { 0xBC14, 0xD0D5, 0xCCB4, 0, 0 };
+static sal_Unicode const aGungsuh[] = { 0xAD81, 0xC11C, 0, 0 };
+static sal_Unicode const aGungsuhChe[] = { 0xAD81, 0xC11C, 0xCCB4, 0, 0 };
+static sal_Unicode const aGulim[] = { 0xAD74, 0xB9BC, 0, 0 };
+static sal_Unicode const aGulimChe[] = { 0xAD74, 0xB9BC, 0xCCB4, 0, 0 };
+static sal_Unicode const aDotum[] = { 0xB3CB, 0xC6C0, 0, 0 };
+static sal_Unicode const aDotumChe[] = { 0xB3CB, 0xC6C0, 0xCCB4, 0, 0 };
+static sal_Unicode const aSimSun[] = { 0x5B8B, 0x4F53, 0, 0 };
+static sal_Unicode const aNSimSun[] = { 0x65B0, 0x5B8B, 0x4F53, 0, 0 };
+static sal_Unicode const aSimHei[] = { 0x9ED1, 0x4F53, 0, 0 };
+static sal_Unicode const aSimKai[] = { 0x6977, 0x4F53, 0, 0 };
+static sal_Unicode const azycjkSun[] = { 0x4E2D, 0x6613, 0x5B8B, 0x4F53, 0, 0 };
+static sal_Unicode const azycjkHei[] = { 0x4E2D, 0x6613, 0x9ED1, 0x4F53, 0, 0 };
+static sal_Unicode const azycjkKai[] = { 0x4E2D, 0x6613, 0x6977, 0x4F53, 0, 0 };
+static sal_Unicode const aFZHei[] = { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0, 0 };
+static sal_Unicode const aFZKai[] = { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0, 0 };
+static sal_Unicode const aFZSongYI[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4E00, 0, 0 };
+static sal_Unicode const aFZShuSong[] = { 0x65B9, 0x6B63, 0x4E66, 0x5B8B, 0, 0 };
+static sal_Unicode const aFZFangSong[] = { 0x65B9, 0x6B63, 0x4EFF, 0x5B8B, 0, 0 };
+// Attention: this fonts includes the wrong encoding vector - so we double the names with correct and wrong encoding
+// First one is the GB-Encoding (we think the correct one), second is the big5 encoded name
+static sal_Unicode const aMHei[] = { 'm', 0x7B80, 0x9ED1, 0, 'm', 0x6F60, 0x7AAA, 0, 0 };
+static sal_Unicode const aMKai[] = { 'm', 0x7B80, 0x6977, 0x566C, 0, 'm', 0x6F60, 0x7FF1, 0x628E, 0, 0 };
+static sal_Unicode const aMSong[] = { 'm', 0x7B80, 0x5B8B, 0, 'm', 0x6F60, 0x51BC, 0, 0 };
+static sal_Unicode const aCFangSong[] = { 'm', 0x7B80, 0x592B, 0x5B8B, 0, 'm', 0x6F60, 0x6E98, 0x51BC, 0, 0 };
+static sal_Unicode const aMingLiU[] = { 0x7D30, 0x660E, 0x9AD4, 0, 0 };
+static sal_Unicode const aPMingLiU[] = { 0x65B0, 0x7D30, 0x660E, 0x9AD4, 0, 0 };
+static sal_Unicode const aHei[] = { 0x6865, 0, 0 };
+static sal_Unicode const aKai[] = { 0x6B61, 0, 0 };
+static sal_Unicode const aMing[] = { 0x6D69, 0x6E67, 0, 0 };
+static sal_Unicode const aMSGothic[] = { 'm','s', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+static sal_Unicode const aMSPGothic[] = { 'm','s','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+static sal_Unicode const aMSMincho[] = { 'm', 's', 0x660E, 0x671D, 0 };
+static sal_Unicode const aMSPMincho[] = { 'm','s','p', 0x660E, 0x671D, 0 };
+static sal_Unicode const aMeiryo[] = { 0x30e1, 0x30a4, 0x30ea, 0x30aa, 0 };
+static sal_Unicode const aHGMinchoL[] = { 'h','g', 0x660E, 0x671D, 'l', 0, 0 };
+static sal_Unicode const aHGGothicB[] = { 'h','g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
+static sal_Unicode const aHGPMinchoL[] = { 'h','g','p', 0x660E, 0x671D, 'l', 0 };
+static sal_Unicode const aHGPGothicB[] = { 'h','g','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
+static sal_Unicode const aHGMinchoLSun[] = { 'h','g', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
+static sal_Unicode const aHGPMinchoLSun[] = { 'h','g','p', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
+static sal_Unicode const aHGGothicBSun[] = { 'h', 'g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
+static sal_Unicode const aHGPGothicBSun[] = { 'h', 'g', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
+static sal_Unicode const aHGHeiseiMin[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 0, 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 'w', '3', 'x', '1', '2', 0, 0 };
+static sal_Unicode const aIPAMincho[] = { 'i', 'p', 'a', 0x660E, 0x671D, 0 };
+static sal_Unicode const aIPAPMincho[] = { 'i', 'p', 'a', 'p', 0x660E, 0x671D, 0 };
+static sal_Unicode const aIPAGothic[] = { 'i', 'p', 'a', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+static sal_Unicode const aIPAPGothic[] = { 'i', 'p', 'a', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+static sal_Unicode const aIPAUIGothic[] = { 'i', 'p', 'a', 'u', 'i', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+static sal_Unicode const aSazanamiMincho[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x660E, 0x671D, 0, 0 };
+static sal_Unicode const aSazanamiGothic[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+static sal_Unicode const aKochiMincho[] = { 0x6771, 0x98A8, 0x660E, 0x671D, 0, 0 };
+static sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
+static sal_Unicode const aSunDotum[] = { 0xC36C, 0xB3CB, 0xC6C0, 0, 0 };
+static sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0, 0 };
+static sal_Unicode const aSunBatang[] = { 0xC36C, 0xBC14, 0xD0D5, 0, 0 };
+static sal_Unicode const aBaekmukDotum[] = { 0xBC31, 0xBB35, 0xB3CB, 0xC6C0, 0, 0 };
+static sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBB35, 0xAD74, 0xB9BC, 0, 0 };
+static sal_Unicode const aBaekmukBatang[] = { 0xBC31, 0xBB35, 0xBC14, 0xD0D5, 0, 0 };
+static sal_Unicode const aFzMingTi[] = { 0x65B9, 0x6B63, 0x660E, 0x9AD4, 0, 0 };
+static sal_Unicode const aFzHeiTiTW[]= { 0x65B9, 0x6B63, 0x9ED1, 0x9AD4, 0, 0 };
+static sal_Unicode const aFzKaiTiTW[]= { 0x65B9, 0x6B63, 0x6977, 0x9AD4, 0, 0 };
+static sal_Unicode const aFzHeiTiCN[]= { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0, 0 };
+static sal_Unicode const aFzKaiTiCN[]= { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0, 0 };
+static sal_Unicode const aFzSongTi[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4F53, 0, 0 };
+static sal_Unicode const aHYMyeongJoExtra[] = { 'h', 'y', 0xACAC, 0xBA85, 0xC870, 0, 0 };
+static sal_Unicode const aHYSinMyeongJoMedium[] = { 'h', 'y', 0xC2E0, 0xBA85, 0xC870, 0, 0 };
+static sal_Unicode const aHYGothicMedium[] = { 'h', 'y', 0xC911, 0xACE0, 0xB515, 0, 0 };
+static sal_Unicode const aHYGraphicMedium[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 'm', 0, 0 };
+static sal_Unicode const aHYGraphic[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 0, 0 };
+static sal_Unicode const aNewGulim[] = { 0xC0C8, 0xAD74, 0xB9BC, 0, 0 };
+static sal_Unicode const aSunGungseo[] = { 0xC36C, 0xAD81, 0xC11C, 0, 0 };
+static sal_Unicode const aHYGungSoBold[] = { 'h','y', 0xAD81, 0xC11C, 'b', 0, 0 };
+static sal_Unicode const aHYGungSo[] = { 'h','y', 0xAD81, 0xC11C, 0, 0 };
+static sal_Unicode const aSunHeadLine[] = { 0xC36C, 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0, 0 };
+static sal_Unicode const aHYHeadLineMedium[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 'm', 0, 0 };
+static sal_Unicode const aHYHeadLine[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0, 0 };
+static sal_Unicode const aYetR[] = { 0xD734, 0xBA3C, 0xC61B, 0xCCB4, 0, 0 };
+static sal_Unicode const aHYGothicExtra[] = { 'h', 'y', 0xACAC, 0xACE0, 0xB515, 0, 0 };
+static sal_Unicode const aSunMokPan[] = { 0xC36C, 0xBAA9, 0xD310, 0, 0 };
+static sal_Unicode const aSunYeopseo[] = { 0xC36C, 0xC5FD, 0xC11C, 0, 0 };
+static sal_Unicode const aSunBaekSong[] = { 0xC36C, 0xBC31, 0xC1A1, 0, 0 };
+static sal_Unicode const aHYPostLight[] = { 'h', 'y', 0xC5FD, 0xC11C, 'l', 0, 0 };
+static sal_Unicode const aHYPost[] = { 'h', 'y', 0xC5FD, 0xC11C, 0, 0 };
+static sal_Unicode const aMagicR[] = { 0xD734, 0xBA3C, 0xB9E4, 0xC9C1, 0xCCB4, 0, 0 };
+static sal_Unicode const aSunCrystal[] = { 0xC36C, 0xD06C, 0xB9AC, 0xC2A4, 0xD0C8, 0, 0 };
+static sal_Unicode const aSunSaemmul[] = { 0xC36C, 0xC0D8, 0xBB3C, 0, 0 };
+static sal_Unicode const aHaansoftBatang[] = { 0xD55C, 0xCEF4, 0xBC14, 0xD0D5, 0, 0 };
+static sal_Unicode const aHaansoftDotum[] = { 0xD55C, 0xCEF4, 0xB3CB, 0xC6C0, 0, 0 };
+static sal_Unicode const aHyhaeseo[] = { 0xD55C, 0xC591, 0xD574, 0xC11C, 0, 0 };
+static sal_Unicode const aMDSol[] = { 'm', 'd', 0xC194, 0xCCB4, 0, 0 };
+static sal_Unicode const aMDGaesung[] = { 'm', 'd', 0xAC1C, 0xC131, 0xCCB4, 0, 0 };
+static sal_Unicode const aMDArt[] = { 'm', 'd', 0xC544, 0xD2B8, 0xCCB4, 0, 0 };
+static sal_Unicode const aMDAlong[] = { 'm', 'd', 0xC544, 0xB871, 0xCCB4, 0, 0 };
+static sal_Unicode const aMDEasop[] = { 'm', 'd', 0xC774, 0xC19D, 0xCCB4, 0, 0 };
+static sal_Unicode const aHYShortSamulMedium[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 'm', 0 };
+static sal_Unicode const aHYShortSamul[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 0 };
+static sal_Unicode const aHGGothicE[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
+static sal_Unicode const aHGPGothicE[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
+static sal_Unicode const aHGSGothicE[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
+static sal_Unicode const aHGGothicM[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
+static sal_Unicode const aHGPGothicM[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
+static sal_Unicode const aHGSGothicM[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
+static sal_Unicode const aHGGyoshotai[] = { 'h','g', 0x884C, 0x66F8, 0x4F53, 0 };
+static sal_Unicode const aHGPGyoshotai[] = { 'h','g','p', 0x884C, 0x66F8, 0x4F53, 0 };
+static sal_Unicode const aHGSGyoshotai[] = { 'h','g','s', 0x884C, 0x66F8, 0x4F53, 0 };
+static sal_Unicode const aHGKyokashotai[] = { 'h','g', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
+static sal_Unicode const aHGPKyokashotai[] = { 'h','g','p', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
+static sal_Unicode const aHGSKyokashotai[] = { 'h','g','s', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
+static sal_Unicode const aHGMinchoB[] = { 'h','g', 0x660E, 0x671D, 'b', 0 };
+static sal_Unicode const aHGPMinchoB[] = { 'h','g','p', 0x660E, 0x671D, 'b', 0 };
+static sal_Unicode const aHGSMinchoB[] = { 'h','g','s', 0x660E, 0x671D, 'b', 0 };
+static sal_Unicode const aHGMinchoE[] = { 'h','g', 0x660E, 0x671D, 'e', 0 };
+static sal_Unicode const aHGPMinchoE[] = { 'h','g','p', 0x660E, 0x671D, 'e', 0 };
+static sal_Unicode const aHGSMinchoE[] = { 'h','g','s', 0x660E, 0x671D, 'e', 0 };
+static sal_Unicode const aHGSoeiKakupoptai[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF8E,
+ 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
+static sal_Unicode const aHGPSoeiKakupoptai[] = { 'h','g', 'p', 0x5275,0x82F1,0x89D2,0xFF8E,
+ 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
+static sal_Unicode const aHGSSoeiKakupoptai[] = { 'h','g', 's', 0x5275,0x82F1,0x89D2,0xFF8E,
+ 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
+static sal_Unicode const aHGSoeiPresenceEB[] = { 'h','g', 0x5275,0x82F1,0xFF8C,0xFF9F,
+ 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
+static sal_Unicode const aHGPSoeiPresenceEB[] = { 'h','g','p', 0x5275,0x82F1,0xFF8C,0xFF9F,
+ 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
+static sal_Unicode const aHGSSoeiPresenceEB[] = { 'h','g','s', 0x5275,0x82F1,0xFF8C,0xFF9F,
+ 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
+static sal_Unicode const aHGSoeiKakugothicUB[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF7A,
+ 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
+static sal_Unicode const aHGPSoeiKakugothicUB[] = { 'h','g','p', 0x5275,0x82F1,0x89D2,0xFF7A,
+ 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
+static sal_Unicode const aHGSSoeiKakugothicUB[] = { 'h','g','s', 0x5275,0x82F1,0x89D2,0xFF7A,
+ 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
+static sal_Unicode const aHGSeikaishotaiPRO[] = { 'h','g', 0x6B63,0x6977,0x66F8,0x4F53, '-','p','r','o',0};
+static sal_Unicode const aHGMaruGothicMPRO[] = { 'h','g', 0x4E38,0xFF7A,0xFF9E,0xFF7C,0xFF6F,0xFF78, '-','p','r','o',0};
+static sal_Unicode const aHiraginoMinchoPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o',0};
+static sal_Unicode const aHiraginoMinchoProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o','n',0};
+static sal_Unicode const aHiraginoKakuGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o',0};
+static sal_Unicode const aHiraginoKakuGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o','n',0};
+static sal_Unicode const aHiraginoMaruGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o',0};
+static sal_Unicode const aHiraginoMaruGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o','n',0};
+
+
+static ImplLocalizedFontName aImplLocalizedNamesList[] =
+{
+{ "batang", aBatang },
+{ "batangche", aBatangChe },
+{ "gungshu", aGungsuh },
+{ "gungshuche", aGungsuhChe },
+{ "gulim", aGulim },
+{ "gulimche", aGulimChe },
+{ "dotum", aDotum },
+{ "dotumche", aDotumChe },
+{ "simsun", aSimSun },
+{ "nsimsun", aNSimSun },
+{ "simhei", aSimHei },
+{ "simkai", aSimKai },
+{ "zycjksun", azycjkSun },
+{ "zycjkhei", azycjkHei },
+{ "zycjkkai", azycjkKai },
+{ "fzhei", aFZHei },
+{ "fzkai", aFZKai },
+{ "fzsong", aFZSongYI },
+{ "fzshusong", aFZShuSong },
+{ "fzfangsong", aFZFangSong },
+{ "mhei", aMHei },
+{ "mkai", aMKai },
+{ "msong", aMSong },
+{ "cfangsong", aCFangSong },
+{ "mingliu", aMingLiU },
+{ "pmingliu", aPMingLiU },
+{ "hei", aHei },
+{ "kai", aKai },
+{ "ming", aMing },
+{ "msgothic", aMSGothic },
+{ "mspgothic", aMSPGothic },
+{ "msmincho", aMSMincho },
+{ "mspmincho", aMSPMincho },
+{ "meiryo", aMeiryo },
+{ "hgminchol", aHGMinchoL },
+{ "hggothicb", aHGGothicB },
+{ "hgpminchol", aHGPMinchoL },
+{ "hgpgothicb", aHGPGothicB },
+{ "hgmincholsun", aHGMinchoLSun },
+{ "hggothicbsun", aHGGothicBSun },
+{ "hgpmincholsun", aHGPMinchoLSun },
+{ "hgpgothicbsun", aHGPGothicBSun },
+{ "hgheiseimin", aHGHeiseiMin },
+{ "ipamincho", aIPAMincho },
+{ "ipapmincho", aIPAPMincho },
+{ "ipagothic", aIPAGothic },
+{ "ipapgothic", aIPAPGothic },
+{ "ipauigothic", aIPAUIGothic },
+{ "sazanamimincho", aSazanamiMincho },
+{ "sazanamigothic", aSazanamiGothic },
+{ "kochimincho", aKochiMincho },
+{ "kochigothic", aKochiGothic },
+{ "sundotum", aSunDotum },
+{ "sungulim", aSunGulim },
+{ "sunbatang", aSunBatang },
+{ "baekmukdotum", aBaekmukDotum },
+{ "baekmukgulim", aBaekmukGulim },
+{ "baekmukbatang", aBaekmukBatang },
+{ "fzheiti", aFzHeiTiCN },
+{ "fzheiti", aFzHeiTiTW },
+{ "fzkaiti", aFzKaiTiCN },
+{ "fzkaitib", aFzKaiTiTW },
+{ "fzmingtib", aFzMingTi },
+{ "fzsongti", aFzSongTi },
+{ "hymyeongjoextra", aHYMyeongJoExtra },
+{ "hysinmyeongjomedium", aHYSinMyeongJoMedium },
+{ "hygothicmedium", aHYGothicMedium },
+{ "hygraphicmedium", aHYGraphicMedium },
+{ "hygraphic", aHYGraphic },
+{ "newgulim", aNewGulim },
+{ "sungungseo", aSunGungseo },
+{ "hygungsobold", aHYGungSoBold },
+{ "hygungso", aHYGungSo },
+{ "sunheadline", aSunHeadLine },
+{ "hyheadlinemedium", aHYHeadLineMedium },
+{ "hyheadline", aHYHeadLine },
+{ "yetr", aYetR },
+{ "hygothicextra", aHYGothicExtra },
+{ "sunmokpan", aSunMokPan },
+{ "sunyeopseo", aSunYeopseo },
+{ "sunbaeksong", aSunBaekSong },
+{ "hypostlight", aHYPostLight },
+{ "hypost", aHYPost },
+{ "magicr", aMagicR },
+{ "suncrystal", aSunCrystal },
+{ "sunsaemmul", aSunSaemmul },
+{ "hyshortsamulmedium", aHYShortSamulMedium },
+{ "hyshortsamul", aHYShortSamul },
+{ "haansoftbatang", aHaansoftBatang },
+{ "haansoftdotum", aHaansoftDotum },
+{ "hyhaeseo", aHyhaeseo },
+{ "mdsol", aMDSol },
+{ "mdgaesung", aMDGaesung },
+{ "mdart", aMDArt },
+{ "mdalong", aMDAlong },
+{ "mdeasop", aMDEasop },
+{ "hggothice", aHGGothicE },
+{ "hgpgothice", aHGPGothicE },
+{ "hgpothice", aHGSGothicE },
+{ "hggothicm", aHGGothicM },
+{ "hgpgothicm", aHGPGothicM },
+{ "hgpgothicm", aHGSGothicM },
+{ "hggyoshotai", aHGGyoshotai },
+{ "hgpgyoshotai", aHGPGyoshotai },
+{ "hgsgyoshotai", aHGSGyoshotai },
+{ "hgkyokashotai", aHGKyokashotai },
+{ "hgpkyokashotai", aHGPKyokashotai },
+{ "hgskyokashotai", aHGSKyokashotai },
+{ "hgminchob", aHGMinchoB },
+{ "hgpminchob", aHGPMinchoB },
+{ "hgsminchob", aHGSMinchoB },
+{ "hgminchoe", aHGMinchoE },
+{ "hgpminchoe", aHGPMinchoE },
+{ "hgsminchoe", aHGSMinchoE },
+{ "hgsoeikakupoptai", aHGSoeiKakupoptai },
+{ "hgpsoeikakupopta", aHGPSoeiKakupoptai },
+{ "hgssoeikakupopta", aHGSSoeiKakupoptai },
+{ "hgsoeipresenceeb", aHGSoeiPresenceEB },
+{ "hgpsoeipresenceeb", aHGPSoeiPresenceEB },
+{ "hgssoeipresenceeb", aHGSSoeiPresenceEB },
+{ "hgsoeikakugothicub", aHGSoeiKakugothicUB },
+{ "hgpsoeikakugothicub", aHGPSoeiKakugothicUB },
+{ "hgssoeikakugothicub", aHGSSoeiKakugothicUB },
+{ "hgseikaishotaipro", aHGSeikaishotaiPRO },
+{ "hgmarugothicmpro", aHGMaruGothicMPRO },
+{ "hiraginominchopro", aHiraginoMinchoPro },
+{ "hiraginominchopron", aHiraginoMinchoProN },
+{ "hiraginokakugothicpro", aHiraginoKakuGothicPro },
+{ "hiraginokakugothicpron", aHiraginoKakuGothicProN },
+{ "hiraginomarugothicpro", aHiraginoMaruGothicPro },
+{ "hiraginomarugothicpron", aHiraginoMaruGothicProN },
+{ NULL, NULL },
+};
+
+// -----------------------------------------------------------------------
+
+void GetEnglishSearchFontName( String& rName )
+{
+ bool bNeedTranslation = false;
+ xub_StrLen nLen = rName.Len();
+
+ // Remove trailing whitespaces
+ xub_StrLen i = nLen;
+ while ( i && (rName.GetChar( i-1 ) < 32) )
+ i--;
+ if ( i != nLen )
+ rName.Erase( i );
+
+ // Remove Script at the end
+ // Scriptname must be the last part of the fontname and
+ // looks like "fontname (scriptname)". So there can only be a
+ // script name at the and of the fontname, when the last char is ')'
+ if ( (nLen >= 3) && rName.GetChar( nLen-1 ) == ')' )
+ {
+ int nOpen = 1;
+ xub_StrLen nTempLen = nLen-2;
+ while ( nTempLen )
+ {
+ if ( rName.GetChar( nTempLen ) == '(' )
+ {
+ nOpen--;
+ if ( !nOpen )
+ {
+ // Remove Space at the end
+ if ( nTempLen && (rName.GetChar( nTempLen-1 ) == ' ') )
+ nTempLen--;
+ rName.Erase( nTempLen );
+ nLen = nTempLen;
+ break;
+ }
+ }
+ if ( rName.GetChar( nTempLen ) == ')' )
+ nOpen++;
+ nTempLen--;
+ }
+ }
+
+ // remove all whitespaces and converts to lower case ASCII
+ // TODO: better transliteration to ASCII e.g. all digits
+ i = 0;
+ while ( i < nLen )
+ {
+ sal_Unicode c = rName.GetChar( i );
+ if ( c > 127 )
+ {
+ // Translate to Lowercase-ASCII
+ // FullWidth-ASCII to half ASCII
+ if ( (c >= 0xFF00) && (c <= 0xFF5E) )
+ {
+ c -= 0xFF00-0x0020;
+ // Upper to Lower
+ if ( (c >= 'A') && (c <= 'Z') )
+ c += 'a' - 'A';
+ rName.SetChar( i, c );
+ }
+ else
+ {
+ // Only Fontnames with None-Ascii-Characters must be translated
+ bNeedTranslation = true;
+ }
+ }
+ // not lowercase Ascii
+ else if ( !((c >= 'a') && (c <= 'z')) )
+ {
+ // To Lowercase-Ascii
+ if ( (c >= 'A') && (c <= 'Z') )
+ {
+ c += 'a' - 'A';
+ rName.SetChar( i, c );
+ }
+ else if( ((c < '0') || (c > '9')) && (c != ';') ) // not 0-9 or semicolon
+ {
+ // Remove white spaces and special characters
+ rName.Erase( i, 1 );
+ nLen--;
+ continue;
+ }
+ }
+
+ i++;
+ }
+
+ // translate normalized localized name to its normalized English ASCII name
+ if( bNeedTranslation )
+ {
+ typedef std::hash_map<const String, const char*,FontNameHash> FontNameDictionary;
+ static FontNameDictionary aDictionary( sizeof(aImplLocalizedNamesList) / sizeof(*aImplLocalizedNamesList) );
+ // the font name dictionary needs to be intialized once
+ if( aDictionary.empty() )
+ {
+ // TODO: check if all dictionary entries are already normalized?
+ const ImplLocalizedFontName* pList = aImplLocalizedNamesList;
+ for(; pList->mpEnglishName; ++pList )
+ aDictionary[ pList->mpLocalizedNames ] = pList->mpEnglishName;
+ }
+
+ FontNameDictionary::const_iterator it = aDictionary.find( rName );
+ if( it != aDictionary.end() )
+ rName.AssignAscii( it->second );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+String GetNextFontToken( const String& rTokenStr, xub_StrLen& rIndex )
+{
+ // check for valid start index
+ int nStringLen = rTokenStr.Len();
+ if( rIndex >= nStringLen )
+ {
+ rIndex = STRING_NOTFOUND;
+ return String();
+ }
+
+ // find the next token delimiter and return the token substring
+ const sal_Unicode* pStr = rTokenStr.GetBuffer() + rIndex;
+ const sal_Unicode* pEnd = rTokenStr.GetBuffer() + nStringLen;
+ for(; pStr < pEnd; ++pStr )
+ if( (*pStr == ';') || (*pStr == ',') )
+ break;
+
+ xub_StrLen nTokenStart = rIndex;
+ xub_StrLen nTokenLen;
+ if( pStr < pEnd )
+ {
+ rIndex = sal::static_int_cast<xub_StrLen>(pStr - rTokenStr.GetBuffer());
+ nTokenLen = rIndex - nTokenStart;
+ ++rIndex; // skip over token separator
+ }
+ else
+ {
+ // no token delimiter found => handle last token
+ rIndex = STRING_NOTFOUND;
+ nTokenLen = STRING_LEN;
+
+ // optimize if the token string consists of just one token
+ if( !nTokenStart )
+ return rTokenStr;
+ }
+
+ return String( rTokenStr, nTokenStart, nTokenLen );
+}
+
+// TODO: get rid of this in another incompatible build with SW project.
+// SW's WW8 and RTF filters still use this (from fontcvt.hxx)
+String GetFontToken( const String& rTokenStr, xub_StrLen nToken, xub_StrLen& rIndex )
+{
+ // skip nToken Tokens
+ for( xub_StrLen i = 0; (i < nToken) && (rIndex != STRING_NOTFOUND); ++i )
+ GetNextFontToken( rTokenStr, rIndex );
+
+ return GetNextFontToken( rTokenStr, rIndex );
+}
+
+// =======================================================================
+
+static bool ImplIsFontToken( const String& rName, const String& rToken )
+{
+ String aTempName;
+ xub_StrLen nIndex = 0;
+ do
+ {
+ aTempName = GetNextFontToken( rName, nIndex );
+ if ( rToken == aTempName )
+ return true;
+ }
+ while ( nIndex != STRING_NOTFOUND );
+
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplAppendFontToken( String& rName, const String& rNewToken )
+{
+ if ( rName.Len() )
+ {
+ rName.Append( ';' );
+ rName.Append( rNewToken );
+ }
+ else
+ rName = rNewToken;
+}
+
+void AddTokenFontName( String& rName, const String& rNewToken )
+{
+ if ( !ImplIsFontToken( rName, rNewToken ) )
+ ImplAppendFontToken( rName, rNewToken );
+}
+
+
+
+// =======================================================================
+
+String GetSubsFontName( const String& rName, ULONG nFlags )
+{
+ String aName;
+
+ xub_StrLen nIndex = 0;
+ String aOrgName = GetNextFontToken( rName, nIndex );
+ GetEnglishSearchFontName( aOrgName );
+
+ // #93662# do not try to replace StarSymbol with MS only font
+ if( nFlags == (SUBSFONT_MS|SUBSFONT_ONLYONE)
+ && ( aOrgName.EqualsAscii( "starsymbol" )
+ || aOrgName.EqualsAscii( "opensymbol" ) ) )
+ return aName;
+
+ const utl::FontNameAttr* pAttr = utl::FontSubstConfiguration::get()->getSubstInfo( aOrgName );
+ if ( pAttr )
+ {
+ for( int i = 0; i < 3; i++ )
+ {
+ const ::std::vector< String >* pVector = NULL;
+ switch( i )
+ {
+ case 0:
+ if( nFlags & SUBSFONT_MS && pAttr->MSSubstitutions.size() )
+ pVector = &pAttr->MSSubstitutions;
+ break;
+ case 1:
+ if( nFlags & SUBSFONT_PS && pAttr->PSSubstitutions.size() )
+ pVector = &pAttr->PSSubstitutions;
+ break;
+ case 2:
+ if( nFlags & SUBSFONT_HTML && pAttr->HTMLSubstitutions.size() )
+ pVector = &pAttr->HTMLSubstitutions;
+ break;
+ }
+ if( ! pVector )
+ continue;
+ for( ::std::vector< String >::const_iterator it = pVector->begin(); it != pVector->end(); ++it )
+ if( ! ImplIsFontToken( rName, *it ) )
+ {
+ ImplAppendFontToken( aName, *it );
+ if( nFlags & SUBSFONT_ONLYONE )
+ {
+ i = 4;
+ break;
+ }
+ }
+ }
+ }
+
+ return aName;
+}
+
+// -----------------------------------------------------------------------
+
+// TODO: use a more generic String hash
+int FontNameHash::operator()( const String& rStr ) const
+{
+ // this simple hash just has to be good enough for font names
+ int nHash = 0;
+ const int nLen = rStr.Len();
+ const sal_Unicode* p = rStr.GetBuffer();
+ switch( nLen )
+ {
+ default: nHash = (p[0]<<16) - (p[1]<<8) + p[2];
+ nHash += nLen;
+ p += nLen - 3;
+ // fall through
+ case 3: nHash += (p[2]<<16); // fall through
+ case 2: nHash += (p[1]<<8); // fall through
+ case 1: nHash += p[0]; // fall through
+ case 0: break;
+ };
+
+ return nHash;
+}
+
diff --git a/unotools/source/misc/makefile.mk b/unotools/source/misc/makefile.mk
index 4d9f7f40746b..d588a216c159 100644
--- a/unotools/source/misc/makefile.mk
+++ b/unotools/source/misc/makefile.mk
@@ -47,6 +47,8 @@ SLOFILES= $(SLO)$/atom.obj \
$(SLO)$/datetime.obj \
$(SLO)$/syslocale.obj \
$(SLO)$/eventlisteneradapter.obj \
+ $(SLO)$/fontcvt.obj \
+ $(SLO)$/fontdefs.obj \
$(SLO)$/desktopterminationobserver.obj \
$(SLO)$/sharedunocomponent.obj \
$(SLO)$/componentresmodule.obj