summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
Diffstat (limited to 'svtools')
-rw-r--r--svtools/inc/svtools/sampletext.hxx16
-rw-r--r--svtools/source/control/ctrlbox.cxx8
-rw-r--r--svtools/source/misc/sampletext.cxx369
3 files changed, 265 insertions, 128 deletions
diff --git a/svtools/inc/svtools/sampletext.hxx b/svtools/inc/svtools/sampletext.hxx
index 09ba499955fc..f7903d85ed67 100644
--- a/svtools/inc/svtools/sampletext.hxx
+++ b/svtools/inc/svtools/sampletext.hxx
@@ -32,6 +32,7 @@
#include <rtl/ustring.hxx>
#include <unicode/uscript.h>
#include <i18npool/lang.h>
+#include <com/sun/star/i18n/ScriptType.hpp>
#include <vcl/fontcapabilities.hxx>
class OutputDevice;
@@ -41,13 +42,24 @@ SVT_DLLPUBLIC UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCovera
SVT_DLLPUBLIC bool isSymbolFont(const Font &rFont);
SVT_DLLPUBLIC bool isOpenSymbolFont(const Font &rFont);
+
SVT_DLLPUBLIC bool canRenderNameOfSelectedFont(OutputDevice &rDevice);
-SVT_DLLPUBLIC rtl::OUString makeRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice);
-SVT_DLLPUBLIC rtl::OUString makeRepresentativeTextForSelectedFont(OutputDevice &rDevice);
+//These ones are typically for use in the font dropdown box beside the
+//fontname, so say things roughly like "Script/Alphabet/Name-Of-Major-Language"
+SVT_DLLPUBLIC rtl::OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice);
+SVT_DLLPUBLIC rtl::OUString makeShortRepresentativeTextForSelectedFont(OutputDevice &rDevice);
+SVT_DLLPUBLIC rtl::OUString makeShortRepresentativeTextForScript(UScriptCode eScript);
+//For the cases where the font doesn't fully support a script, but has partial support
+//for a useful subset
+SVT_DLLPUBLIC rtl::OUString makeShortMinimalTextForScript(UScriptCode eScript);
+
+//These ones are typically for use in the font preview window in format character
+SVT_DLLPUBLIC rtl::OUString makeRepresentativeTextForFont(sal_Int16 nScriptType, const Font &rFont);
SVT_DLLPUBLIC rtl::OUString makeRepresentativeTextForLanguage(LanguageType eLang);
SVT_DLLPUBLIC rtl::OUString makeRepresentativeTextForScript(UScriptCode eScript);
SVT_DLLPUBLIC rtl::OUString makeMinimalTextForScript(UScriptCode eScript);
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index bf412d4b8cc3..e602cefe9c5c 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -1344,7 +1344,7 @@ void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
const bool bNameBeginsWithLatinText = rInfo.GetName().GetChar(0) <= 'z';
if (bNameBeginsWithLatinText || !bUsingCorrectFont)
- sSampleText = makeRepresentativeTextForSelectedFont(*rUDEvt.GetDevice());
+ sSampleText = makeShortRepresentativeTextForSelectedFont(*rUDEvt.GetDevice());
}
//If we're not a symbol font, but could neither render our own name and
@@ -1389,7 +1389,7 @@ void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
for (size_t i = 0; i < SAL_N_ELEMENTS(aScripts); ++i)
{
- rtl::OUString sText = makeRepresentativeTextForScript(aScripts[i]);
+ rtl::OUString sText = makeShortRepresentativeTextForScript(aScripts[i]);
if (!sText.isEmpty())
{
bool bHasSampleTextGlyphs = (STRING_LEN == rUDEvt.GetDevice()->HasGlyphs(aFont, sText));
@@ -1409,7 +1409,7 @@ void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
for (size_t i = 0; i < SAL_N_ELEMENTS(aMinimalScripts); ++i)
{
- rtl::OUString sText = makeMinimalTextForScript(aMinimalScripts[i]);
+ rtl::OUString sText = makeShortMinimalTextForScript(aMinimalScripts[i]);
if (!sText.isEmpty())
{
bool bHasSampleTextGlyphs = (STRING_LEN == rUDEvt.GetDevice()->HasGlyphs(aFont, sText));
@@ -1426,7 +1426,7 @@ void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
//render something representative of what it would like to render then
//make up some semi-random text that it *can* display
if (bSymbolFont || (!bUsingCorrectFont && sSampleText.isEmpty()))
- sSampleText = makeRepresentativeSymbolTextForSelectedFont(*rUDEvt.GetDevice());
+ sSampleText = makeShortRepresentativeSymbolTextForSelectedFont(*rUDEvt.GetDevice());
if (sSampleText.getLength())
{
diff --git a/svtools/source/misc/sampletext.cxx b/svtools/source/misc/sampletext.cxx
index 45a6ba9f888b..b0f554c2ca9b 100644
--- a/svtools/source/misc/sampletext.cxx
+++ b/svtools/source/misc/sampletext.cxx
@@ -29,7 +29,9 @@
#include <svtools/sampletext.hxx>
#include <vcl/font.hxx>
#include <vcl/outdev.hxx>
+#include <vcl/virdev.hxx>
#include <vcl/metric.hxx>
+#include <i18nutil/unicode.hxx>
bool isOpenSymbolFont(const Font &rFont)
{
@@ -65,7 +67,7 @@ bool canRenderNameOfSelectedFont(OutputDevice &rDevice)
return !isSymbolFont(rFont) && (STRING_LEN == rDevice.HasGlyphs(rFont, rFont.GetName()));
}
-rtl::OUString makeRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
+rtl::OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
{
const bool bOpenSymbol = isOpenSymbolFont(rDevice.GetFont());
@@ -127,7 +129,7 @@ rtl::OUString makeRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
//readers of the minor languages, e.g. Yiddish is written with the HEBREW
//script as well, the vast majority of Yiddish readers will be able to read
//Hebrew as well.
-rtl::OUString makeRepresentativeTextForScript(UScriptCode eScript)
+rtl::OUString makeShortRepresentativeTextForScript(UScriptCode eScript)
{
rtl::OUString sSampleText;
switch (eScript)
@@ -410,7 +412,54 @@ rtl::OUString makeRepresentativeTextForScript(UScriptCode eScript)
return sSampleText;
}
-rtl::OUString makeMinimalTextForScript(UScriptCode eScript)
+rtl::OUString makeRepresentativeTextForScript(UScriptCode eScript)
+{
+ rtl::OUString sSampleText;
+ switch (eScript)
+ {
+ case USCRIPT_TRADITIONAL_HAN:
+ case USCRIPT_SIMPLIFIED_HAN:
+ case USCRIPT_HAN:
+ {
+ //Three Character Classic
+ const sal_Unicode aZh[] = {
+ 0x4EBA, 0x4E4B, 0x521D, 0x0020, 0x6027, 0x672C, 0x5584
+ };
+ sSampleText = rtl::OUString(aZh, SAL_N_ELEMENTS(aZh));
+ break;
+ }
+ case USCRIPT_JAPANESE:
+ {
+ //Iroha
+ const sal_Unicode aJa[] = {
+ 0x8272, 0x306F, 0x5302, 0x3078, 0x3069, 0x0020, 0x6563,
+ 0x308A, 0x306C, 0x308B, 0x3092
+ };
+ sSampleText = rtl::OUString(aJa, SAL_N_ELEMENTS(aJa));
+ break;
+ }
+ case USCRIPT_KOREAN:
+ case USCRIPT_HANGUL:
+ {
+ //The essential condition for...
+ const sal_Unicode aKo[] = {
+ 0xD0A4, 0xC2A4, 0xC758, 0x0020, 0xACE0, 0xC720, 0xC870,
+ 0xAC74, 0xC740
+ };
+ sSampleText = rtl::OUString(aKo, SAL_N_ELEMENTS(aKo));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (sSampleText.isEmpty())
+ sSampleText = makeShortRepresentativeTextForScript(eScript);
+ return sSampleText;
+
+}
+
+rtl::OUString makeShortMinimalTextForScript(UScriptCode eScript)
{
rtl::OUString sSampleText;
switch (eScript)
@@ -437,34 +486,27 @@ rtl::OUString makeMinimalTextForScript(UScriptCode eScript)
return sSampleText;
}
+rtl::OUString makeMinimalTextForScript(UScriptCode eScript)
+{
+ return makeShortMinimalTextForScript(eScript);
+}
+
//These ones are typically for use in the font preview window in format
//character
//
//There we generally know the language. Though its possible for the language to
//be "none".
//
-//Currently we fall back to makeRepresentativeTextForScript as I don't have
-//suitable strings
+//Currently we fall back to makeShortRepresentativeTextForScript when we don't
+//have suitable strings
rtl::OUString makeRepresentativeTextForLanguage(LanguageType eLang)
{
- switch( eLang )
- {
- case LANGUAGE_CHINESE:
- return makeRepresentativeTextForScript(USCRIPT_HAN);
-
- case LANGUAGE_CHINESE_TRADITIONAL:
- case LANGUAGE_CHINESE_HONGKONG:
- case LANGUAGE_CHINESE_MACAU:
- return makeRepresentativeTextForScript(USCRIPT_TRADITIONAL_HAN);
-
- case LANGUAGE_CHINESE_SIMPLIFIED:
- case LANGUAGE_CHINESE_SINGAPORE:
- return makeRepresentativeTextForScript(USCRIPT_SIMPLIFIED_HAN);
- }
-
rtl::OUString sRet;
switch( eLang & LANGUAGE_MASK_PRIMARY )
{
+ case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY:
+ sRet = makeRepresentativeTextForScript(USCRIPT_HAN);
+ break;
case LANGUAGE_GREEK & LANGUAGE_MASK_PRIMARY:
sRet = makeRepresentativeTextForScript(USCRIPT_GREEK);
break;
@@ -893,47 +935,74 @@ namespace
}
#endif
+ boost::dynamic_bitset<sal_uInt32> getMaskByScriptType(sal_Int16 nScriptType)
+ {
+ boost::dynamic_bitset<sal_uInt32> aMask(vcl::UnicodeCoverage::MAX_UC_ENUM);
+ aMask.set();
+
+ for (size_t i = 0; i < vcl::UnicodeCoverage::MAX_UC_ENUM; ++i)
+ {
+ using vcl::UnicodeCoverage::UnicodeCoverageEnum;
+ UScriptCode eScriptCode = otCoverageToScript(static_cast<UnicodeCoverageEnum>(i));
+ if (unicode::getScriptClassFromUScriptCode(eScriptCode) == nScriptType)
+ aMask.set(i, false);
+ }
+
+ return aMask;
+ }
+
+ //false for all bits considered "Latin" by LibreOffice
+ boost::dynamic_bitset<sal_uInt32> getLatinMask()
+ {
+ static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::LATIN));
+ return aMask;
+ }
+
+ //false for all bits considered "Asian" by LibreOffice
+ boost::dynamic_bitset<sal_uInt32> getCJKMask()
+ {
+ static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::ASIAN));
+ return aMask;
+ }
+
+ //false for all bits considered "Complex" by LibreOffice
+ boost::dynamic_bitset<sal_uInt32> getCTLMask()
+ {
+ static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::COMPLEX));
+ return aMask;
+ }
+
+ //false for all bits considered "WEAK" by LibreOffice
+ boost::dynamic_bitset<sal_uInt32> getWeakMask()
+ {
+ static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::WEAK));
+ return aMask;
+ }
+
+ //Nearly every font supports some basic Latin
+ boost::dynamic_bitset<sal_uInt32> getCommonLatnSubsetMask()
+ {
+ boost::dynamic_bitset<sal_uInt32> aMask(vcl::UnicodeCoverage::MAX_UC_ENUM);
+ aMask.set();
+ aMask.set(vcl::UnicodeCoverage::BASIC_LATIN, false);
+ aMask.set(vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT, false);
+ aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_A, false);
+ aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_B, false);
+ aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL, false);
+ return aMask;
+ }
+
+ boost::dynamic_bitset<sal_uInt32> getGenericMask()
+ {
+ static boost::dynamic_bitset<sal_uInt32> aMask(getWeakMask() & getCommonLatnSubsetMask());
+ return aMask;
+ }
+
UScriptCode getScript(const vcl::FontCapabilities &rFontCapabilities)
{
using vcl::UnicodeCoverage::UnicodeCoverageEnum;
- boost::dynamic_bitset<sal_uInt32> aGenericMask(vcl::UnicodeCoverage::MAX_UC_ENUM);
- aGenericMask.set();
- aGenericMask.set(vcl::UnicodeCoverage::BASIC_LATIN, false);
- aGenericMask.set(vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT, false);
- aGenericMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_A, false);
- aGenericMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_B, false);
- aGenericMask.set(vcl::UnicodeCoverage::IPA_EXTENSIONS, false);
- aGenericMask.set(vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS, false);
- aGenericMask.set(vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS, false);
- aGenericMask.set(vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, false);
- aGenericMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL, false);
- aGenericMask.set(vcl::UnicodeCoverage::GENERAL_PUNCTUATION, false);
- aGenericMask.set(vcl::UnicodeCoverage::GEOMETRIC_SHAPES, false);
- aGenericMask.set(vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS, false);
- aGenericMask.set(vcl::UnicodeCoverage::CURRENCY_SYMBOLS, false);
- aGenericMask.set(vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS, false);
- aGenericMask.set(vcl::UnicodeCoverage::DINGBATS, false);
- aGenericMask.set(vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0, false);
- aGenericMask.set(vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS, false);
- aGenericMask.set(vcl::UnicodeCoverage::NUMBER_FORMS, false);
- aGenericMask.set(vcl::UnicodeCoverage::ARROWS, false);
- aGenericMask.set(vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS, false);
- aGenericMask.set(vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS, false);
- aGenericMask.set(vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL, false);
- aGenericMask.set(vcl::UnicodeCoverage::CONTROL_PICTURES, false);
- aGenericMask.set(vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS, false);
- aGenericMask.set(vcl::UnicodeCoverage::BOX_DRAWING, false);
- aGenericMask.set(vcl::UnicodeCoverage::BLOCK_ELEMENTS, false);
- aGenericMask.set(vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS, false);
- aGenericMask.set(vcl::UnicodeCoverage::SPECIALS, false);
- aGenericMask.set(vcl::UnicodeCoverage::NONPLANE_0, false);
- aGenericMask.set(vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15, false);
- aGenericMask.set(vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION, false);
- aGenericMask.set(vcl::UnicodeCoverage::VARIATION_SELECTORS, false);
- aGenericMask.set(vcl::UnicodeCoverage::VERTICAL_FORMS, false);
-
- boost::dynamic_bitset<sal_uInt32> aMasked = rFontCapabilities.maUnicodeRange & aGenericMask;
+ boost::dynamic_bitset<sal_uInt32> aMasked = rFontCapabilities.maUnicodeRange & getGenericMask();
if (aMasked.count() == 1)
return otCoverageToScript(static_cast<UnicodeCoverageEnum>(aMasked.find_first()));
@@ -970,29 +1039,13 @@ namespace
return USCRIPT_GEORGIAN;
}
- boost::dynamic_bitset<sal_uInt32> aCJKMask(vcl::UnicodeCoverage::MAX_UC_ENUM);
- aCJKMask.set();
- aCJKMask.set(vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION, false);
- aCJKMask.set(vcl::UnicodeCoverage::HIRAGANA, false);
- aCJKMask.set(vcl::UnicodeCoverage::KATAKANA, false);
- aCJKMask.set(vcl::UnicodeCoverage::HANGUL_JAMO, false);
- aCJKMask.set(vcl::UnicodeCoverage::HANGUL_SYLLABLES, false);
- aCJKMask.set(vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO, false);
- aCJKMask.set(vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS, false);
- aCJKMask.set(vcl::UnicodeCoverage::CJK_COMPATIBILITY, false);
- aCJKMask.set(vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS, false);
- aCJKMask.set(vcl::UnicodeCoverage::CJK_STROKES, false);
- aCJKMask.set(vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS, false);
- aCJKMask.set(vcl::UnicodeCoverage::BOPOMOFO, false);
- aCJKMask.set(vcl::UnicodeCoverage::SMALL_FORM_VARIANTS, false);
- aCJKMask.set(vcl::UnicodeCoverage::PHAGS_PA, false);
- aCJKMask.set(vcl::UnicodeCoverage::CYRILLIC, false);
- aCJKMask.set(vcl::UnicodeCoverage::THAI, false);
- aCJKMask.set(vcl::UnicodeCoverage::DESERET, false);
-
- aMasked = aMasked & aCJKMask;
-
- //So, apparently a CJK font
+ aMasked &= getCJKMask();
+
+ aMasked.set(vcl::UnicodeCoverage::CYRILLIC, false);
+ aMasked.set(vcl::UnicodeCoverage::THAI, false);
+ aMasked.set(vcl::UnicodeCoverage::DESERET, false);
+
+ //So, possibly a CJK font
if (!aMasked.count())
{
boost::dynamic_bitset<sal_uInt32> aCJKCodePageMask(vcl::CodePageCoverage::MAX_CP_ENUM);
@@ -1022,14 +1075,60 @@ namespace
return USCRIPT_TRADITIONAL_HAN;
}
- return USCRIPT_HAN;
+ if (aMaskedCodePage.count())
+ return USCRIPT_HAN;
}
return USCRIPT_COMMON;
}
}
-rtl::OUString makeRepresentativeTextForSelectedFont(OutputDevice &rDevice)
+namespace
+{
+ UScriptCode attemptToDisambiguateHan(UScriptCode eScript, OutputDevice &rDevice)
+ {
+ //If we're a CJK font, see if we seem to be tuned for C, J or K
+ if (eScript == USCRIPT_HAN)
+ {
+ const Font &rFont = rDevice.GetFont();
+
+ bool bKore = false, bJpan = false, bHant = false, bHans = false;
+
+ const sal_Unicode aKorean[] = { 0x3131 };
+ rtl::OUString sKorean(aKorean, SAL_N_ELEMENTS(aKorean));
+ if (STRING_LEN == rDevice.HasGlyphs(rFont, sKorean))
+ bKore = true;
+
+ const sal_Unicode aJapanese[] = { 0x3007, 0x9F9D };
+ rtl::OUString sJapanese(aJapanese, SAL_N_ELEMENTS(aJapanese));
+ if (STRING_LEN == rDevice.HasGlyphs(rFont, sJapanese))
+ bJpan = true;
+
+ const sal_Unicode aTraditionalChinese[] = { 0x570B };
+ rtl::OUString sTraditionalChinese(aTraditionalChinese, SAL_N_ELEMENTS(aTraditionalChinese));
+ if (STRING_LEN == rDevice.HasGlyphs(rFont, sTraditionalChinese))
+ bHant = true;
+
+ const sal_Unicode aSimplifiedChinese[] = { 0x56FD };
+ rtl::OUString sSimplifiedChinese(aSimplifiedChinese, SAL_N_ELEMENTS(aSimplifiedChinese));
+ if (STRING_LEN == rDevice.HasGlyphs(rFont, sSimplifiedChinese))
+ bHans = true;
+
+ if (bKore && !bJpan && !bHans)
+ eScript = USCRIPT_KOREAN;
+ else if (bJpan && !bKore && !bHant)
+ eScript = USCRIPT_JAPANESE;
+ else if (bHant && !bHans && !bKore && !bJpan)
+ eScript = USCRIPT_TRADITIONAL_HAN;
+ else if (bHans && !bHant && !bKore && !bJpan)
+ eScript = USCRIPT_SIMPLIFIED_HAN;
+ //otherwise fall-through as USCRIPT_HAN and expect a combind Hant/Hans preview
+ }
+ return eScript;
+ }
+}
+
+rtl::OUString makeShortRepresentativeTextForSelectedFont(OutputDevice &rDevice)
{
vcl::FontCapabilities aFontCapabilities;
if (!rDevice.GetFontCapabilities(aFontCapabilities))
@@ -1042,6 +1141,8 @@ rtl::OUString makeRepresentativeTextForSelectedFont(OutputDevice &rDevice)
lcl_dump_codepage_coverage(aFontCapabilities.maCodePageRange);
#endif
+ aFontCapabilities.maUnicodeRange &= getGenericMask();
+
//If this font is probably tuned to display a single non-Latin
//script and the font name is itself in Latin, then show a small
//chunk of representative text for that script
@@ -1049,46 +1150,10 @@ rtl::OUString makeRepresentativeTextForSelectedFont(OutputDevice &rDevice)
if (!eScript != USCRIPT_COMMON)
return rtl::OUString();
- const Font &rFont = rDevice.GetFont();
+ eScript = attemptToDisambiguateHan(eScript, rDevice);
- //If we're a CJK font, see if we seem to be tuned for C, J or K
- if (eScript == USCRIPT_HAN)
- {
- bool bKore = false, bJpan = false, bHant = false, bHans = false;
-
- const sal_Unicode aKorean[] = { 0x3131 };
- rtl::OUString sKorean(aKorean, SAL_N_ELEMENTS(aKorean));
- if (STRING_LEN == rDevice.HasGlyphs(rFont, sKorean))
- bKore = true;
-
- const sal_Unicode aJapanese[] = { 0x3007, 0x9F9D };
- rtl::OUString sJapanese(aJapanese, SAL_N_ELEMENTS(aJapanese));
- if (STRING_LEN == rDevice.HasGlyphs(rFont, sJapanese))
- bJpan = true;
-
- const sal_Unicode aTraditionalChinese[] = { 0x570B };
- rtl::OUString sTraditionalChinese(aTraditionalChinese, SAL_N_ELEMENTS(aTraditionalChinese));
- if (STRING_LEN == rDevice.HasGlyphs(rFont, sTraditionalChinese))
- bHant = true;
-
- const sal_Unicode aSimplifiedChinese[] = { 0x56FD };
- rtl::OUString sSimplifiedChinese(aSimplifiedChinese, SAL_N_ELEMENTS(aSimplifiedChinese));
- if (STRING_LEN == rDevice.HasGlyphs(rFont, sSimplifiedChinese))
- bHans = true;
-
- if (bKore && !bJpan && !bHans)
- eScript = USCRIPT_KOREAN;
- else if (bJpan && !bKore && !bHant)
- eScript = USCRIPT_JAPANESE;
- else if (bHant && !bHans && !bKore && !bJpan)
- eScript = USCRIPT_TRADITIONAL_HAN;
- else if (bHans && !bHant && !bKore && !bJpan)
- eScript = USCRIPT_SIMPLIFIED_HAN;
- //otherwise fall-through as USCRIPT_HAN and expect a combind Hant/Hans preview
- }
-
- rtl::OUString sSampleText = makeRepresentativeTextForScript(eScript);
- bool bHasSampleTextGlyphs = (STRING_LEN == rDevice.HasGlyphs(rFont, sSampleText));
+ rtl::OUString sSampleText = makeShortRepresentativeTextForScript(eScript);
+ bool bHasSampleTextGlyphs = (STRING_LEN == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText));
return bHasSampleTextGlyphs ? sSampleText : rtl::OUString();
}
@@ -1101,7 +1166,6 @@ UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCoverageEnum eOTCove
case vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT:
case vcl::UnicodeCoverage::LATIN_EXTENDED_A:
case vcl::UnicodeCoverage::LATIN_EXTENDED_B:
- case vcl::UnicodeCoverage::IPA_EXTENSIONS:
eRet = USCRIPT_LATIN;
break;
case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS:
@@ -1390,6 +1454,7 @@ UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCoverageEnum eOTCove
case vcl::UnicodeCoverage::PHAISTOS_DISC:
eRet = USCRIPT_SYMBOLS;
break;
+ case vcl::UnicodeCoverage::IPA_EXTENSIONS:
case vcl::UnicodeCoverage::SPECIALS:
case vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS:
case vcl::UnicodeCoverage::VERTICAL_FORMS:
@@ -1413,4 +1478,64 @@ UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCoverageEnum eOTCove
return eRet;
}
+rtl::OUString makeRepresentativeTextForFont(sal_Int16 nScriptType, const Font &rFont)
+{
+ rtl::OUString sRet(makeRepresentativeTextForLanguage(rFont.GetLanguage()));
+
+ if (sRet.isEmpty())
+ {
+ VirtualDevice aDevice;
+ aDevice.SetFont(rFont);
+ vcl::FontCapabilities aFontCapabilities;
+ if (aDevice.GetFontCapabilities(aFontCapabilities))
+ {
+#if OSL_DEBUG_LEVEL > 2
+ lcl_dump_unicode_coverage(aFontCapabilities.maUnicodeRange);
+#endif
+
+ aFontCapabilities.maUnicodeRange &= getWeakMask();
+
+ if (nScriptType != com::sun::star::i18n::ScriptType::ASIAN)
+ {
+ aFontCapabilities.maUnicodeRange &= getCJKMask();
+ aFontCapabilities.maCodePageRange =
+ boost::dynamic_bitset<sal_uInt32>(aFontCapabilities.maCodePageRange.size());
+ }
+ if (nScriptType != com::sun::star::i18n::ScriptType::LATIN)
+ aFontCapabilities.maUnicodeRange &= getLatinMask();
+ if (nScriptType != com::sun::star::i18n::ScriptType::COMPLEX)
+ aFontCapabilities.maUnicodeRange &= getCTLMask();
+
+#if OSL_DEBUG_LEVEL > 2
+ fprintf(stderr, "minimal\n");
+ lcl_dump_unicode_coverage(aFontCapabilities.maUnicodeRange);
+ lcl_dump_codepage_coverage(aFontCapabilities.maCodePageRange);
+#endif
+
+ UScriptCode eScript = getScript(aFontCapabilities);
+
+ if (nScriptType == com::sun::star::i18n::ScriptType::ASIAN)
+ eScript = attemptToDisambiguateHan(eScript, aDevice);
+
+ sRet = makeRepresentativeTextForScript(eScript);
+ }
+
+ if (sRet.isEmpty())
+ {
+ if (nScriptType == com::sun::star::i18n::ScriptType::COMPLEX)
+ {
+ sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW);
+ if (STRING_LEN != aDevice.HasGlyphs(rFont, sRet))
+ {
+ sRet = makeMinimalTextForScript(USCRIPT_HEBREW);
+ if (STRING_LEN != aDevice.HasGlyphs(rFont, sRet))
+ sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC);
+ }
+ }
+ }
+ }
+
+ return sRet;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */