diff options
author | Mathias Bauer <mba@openoffice.org> | 2009-10-19 13:22:39 +0200 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2009-10-19 13:22:39 +0200 |
commit | 942dbe34b9a1400c926a81f88e849d248b58ed55 (patch) | |
tree | 0fe108618106e42e0a25074782c160c393b45ffb /unotools | |
parent | c5ddee96afdc3ceb5bcc023b36185122a16b283d (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.hxx | 230 | ||||
-rw-r--r-- | unotools/inc/unotools/fontcvt.hxx | 82 | ||||
-rw-r--r-- | unotools/inc/unotools/fontdefs.hxx | 110 | ||||
-rw-r--r-- | unotools/source/config/fontcfg.cxx | 1220 | ||||
-rw-r--r-- | unotools/source/config/makefile.mk | 1 | ||||
-rw-r--r-- | unotools/source/misc/fontcvt.cxx | 1523 | ||||
-rw-r--r-- | unotools/source/misc/fontdefs.cxx | 596 | ||||
-rw-r--r-- | unotools/source/misc/makefile.mk | 2 |
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 |