summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2011-10-21 09:33:39 +0100
committerCaolán McNamara <caolanm@redhat.com>2011-10-21 11:27:39 +0100
commite84482a38363004d5dc2fde24e57d4215b48797a (patch)
tree3b060be8bfb764ac030b520d2347be407100a4df /svtools
parent41c083a7ade3feb7f5b6516f859db00fa8e2cf72 (diff)
Use language/script specific CTL/CJK sample text in font preview
i.e. font names are often typically in English, so fairly useless to take the English name to preview what effect the font will have in a CTL/CJK script. More languages and scripts need to be added, but this should be sufficient to bootstrap this up
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: */