diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /svtools/source/misc/sampletext.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svtools/source/misc/sampletext.cxx')
-rw-r--r-- | svtools/source/misc/sampletext.cxx | 1678 |
1 files changed, 1678 insertions, 0 deletions
diff --git a/svtools/source/misc/sampletext.cxx b/svtools/source/misc/sampletext.cxx new file mode 100644 index 000000000..a08c2867a --- /dev/null +++ b/svtools/source/misc/sampletext.cxx @@ -0,0 +1,1678 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include <svtools/sampletext.hxx> +#include <vcl/font.hxx> +#include <vcl/outdev.hxx> +#include <vcl/virdev.hxx> +#include <vcl/fontcharmap.hxx> +#include <i18nutil/unicode.hxx> +#include <sal/log.hxx> +#include <com/sun/star/i18n/ScriptType.hpp> + +// This should only be used when a commonly used font incorrectly declares its +// coverage. If you add a font here, please leave a note explaining the issue +// that caused it to be added +static UScriptCode lcl_getHardCodedScriptNameForFont (const OutputDevice &rDevice) +{ + const OUString &rName = rDevice.GetFont().GetFamilyName(); + + if (rName == "GB18030 Bitmap") + { + // As of OSX 10.9, the system font "GB18030 Bitmap" incorrectly declares + // that it only covers "Phoenician" when in fact it's a Chinese font. + return USCRIPT_HAN; + } + else if (rName == "BiauKai") + { + // "BiauKai" makes crazy claims to cover BUGINESE, SUNDANESE, etc + // but in fact it's a Traditional Chinese font. + return USCRIPT_TRADITIONAL_HAN; + } + else if (rName == "GungSeo" || rName == "PCMyungjo" || rName == "PilGi") + { + // These have no OS/2 tables, but we know they are Korean fonts. + return USCRIPT_KOREAN; + } + else if (rName == "Hei" || rName == "Kai") + { + // These have no OS/2 tables, but we know they are Chinese fonts. + return USCRIPT_HAN; + } + else if (rName.startsWith("Bangla ")) + { + // "Bangla Sangam MN" claims it supports MALAYALAM, but it doesn't + // "Bangla MN" claims just DEVANAGARI and not an additional BENGALI + return USCRIPT_BENGALI; + } + else if (rName.startsWith("Gurmukhi ")) + { + // "Gurmukhi MN" claims it supports TAMIL, but it doesn't + return USCRIPT_GURMUKHI; + } + else if (rName.startsWith("Kannada ")) + { + // "Kannada MN" claims it supports TAMIL, but it doesn't + return USCRIPT_KANNADA; + } + else if (rName.startsWith("Lao ")) + { + // "Lao Sangam MN" claims it supports TAMIL, but it doesn't + return USCRIPT_LAO; + } + else if (rName.startsWith("Malayalam ")) + { + // "Malayalam MN" claims it supports TAMIL, but it doesn't + return USCRIPT_MALAYALAM; + } + else if (rName.startsWith("Sinhala ")) + { + // "Sinhala MN" claims it supports CYRILLIC + return USCRIPT_SINHALA; + } + else if (rName.startsWith("Telugu ")) + { + // "Telugu MN" claims it supports TAMIL, but it doesn't + return USCRIPT_TELUGU; + } + else if (rName.startsWith("Myanmar ")) + { + return USCRIPT_MYANMAR; + } + else if (rName == "InaiMathi") + { + // "InaiMathi" claims it supports GOTHIC and CJK_UNIFIED_IDEOGRAPHS as well as + // TAMIL, but it doesn't + return USCRIPT_TAMIL; + } + else if (rName == "Hannotate TC" || rName == "HanziPen TC" || rName == "Heiti TC" || rName == "Weibei TC") + { + // These fonts claim support for ARMENIAN and a bunch of other stuff they don't support + return USCRIPT_TRADITIONAL_HAN; + } + else if (rName == "Hannotate SC" || rName == "HanziPen SC" || rName == "Heiti SC" || rName == "Weibei SC") + { + // These fonts claim support for ARMENIAN and a bunch of other stuff they don't support + return USCRIPT_SIMPLIFIED_HAN; + } + + return USCRIPT_INVALID_CODE; +} + +bool isSymbolFont(const vcl::Font &rFont) +{ + return (rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL) || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Apple Color Emoji") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("cmsy10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("cmex10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("esint10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("feta26") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("jsMath-cmsy10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("jsMath-cmex10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("msam10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("msbm10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("wasy10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Denemo") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic1") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic2") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic3") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic4") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Letters Laughing") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("MusiQwik") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("MusiSync") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("stmary10") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Symbol") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Webdings") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Wingdings") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Wingdings 2") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Wingdings 3") || + rFont.GetFamilyName().equalsIgnoreAsciiCase("Bookshelf Symbol 7") || + rFont.GetFamilyName().startsWith("STIXIntegrals") || + rFont.GetFamilyName().startsWith("STIXNonUnicode") || + rFont.GetFamilyName().startsWith("STIXSize") || + rFont.GetFamilyName().startsWith("STIXVariants") || + IsStarSymbol(rFont.GetFamilyName()); +} + +bool canRenderNameOfSelectedFont(OutputDevice const &rDevice) +{ + const vcl::Font &rFont = rDevice.GetFont(); + return !isSymbolFont(rFont) && ( -1 == rDevice.HasGlyphs(rFont, rFont.GetFamilyName()) ); +} + +OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice const &rDevice) +{ + if (rDevice.GetFont().GetFamilyName() == "Symbol") + { + static const sal_Unicode aImplAppleSymbolText[] = { + 0x03BC, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x03A9, 0x221A, 0}; + OUString sSampleText(aImplAppleSymbolText); + bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText)); + //It's the Apple version + if (bHasSampleTextGlyphs) + return OUString(aImplAppleSymbolText); + static const sal_Unicode aImplAdobeSymbolText[] = { + 0xF06D, 0xF0B6, 0xF0E5, 0xF0D5, 0xF070, 0xF0F2, 0xF057, 0xF0D6, 0}; + return OUString(aImplAdobeSymbolText); + } + + const bool bOpenSymbol = IsStarSymbol(rDevice.GetFont().GetFamilyName()); + + if (!bOpenSymbol) + { + FontCharMapRef xFontCharMap; + bool bHasCharMap = rDevice.GetFontCharMap(xFontCharMap); + if( bHasCharMap ) + { + // use some sample characters available in the font + sal_Unicode aText[8]; + + // start just above the PUA used by most symbol fonts + sal_uInt32 cNewChar = 0xFF00; + + const int nMaxCount = SAL_N_ELEMENTS(aText) - 1; + int nSkip = xFontCharMap->GetCharCount() / nMaxCount; + if( nSkip > 10 ) + nSkip = 10; + else if( nSkip <= 0 ) + nSkip = 1; + for( int i = 0; i < nMaxCount; ++i ) + { + sal_uInt32 cOldChar = cNewChar; + for( int j = nSkip; --j >= 0; ) + cNewChar = xFontCharMap->GetPrevChar( cNewChar ); + if( cOldChar == cNewChar ) + break; + aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples + aText[ i+1 ] = 0; + } + + return OUString(aText); + } + } + + static const sal_Unicode aImplSymbolFontText[] = { + 0xF021,0xF032,0xF043,0xF054,0xF065,0xF076,0xF0B7,0xF0C8,0}; + static const sal_Unicode aImplStarSymbolText[] = { + 0x2702,0x2708,0x270D,0xE033,0x2211,0x2288,0}; + const sal_Unicode* pText = bOpenSymbol ? aImplStarSymbolText : aImplSymbolFontText; + OUString sSampleText(pText); + bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText)); + return bHasSampleTextGlyphs ? sSampleText : OUString(); +} + +//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" + +//Here we don't always know the language of course, only the script that can be +//written with the font. Often that's one single language written in that +//script, or a handful of related languages where the name of the script is the +//same between languages, or the name in the major language is known by most +//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. +OUString makeShortRepresentativeTextForScript(UScriptCode eScript) +{ + OUString sSampleText; + switch (eScript) + { + case USCRIPT_GREEK: + { + static const sal_Unicode aGrek[] = { + 0x0391, 0x03BB, 0x03C6, 0x03AC, 0x03B2, 0x03B7, 0x03C4, 0x03BF + }; + sSampleText = OUString(aGrek, SAL_N_ELEMENTS(aGrek)); + break; + } + case USCRIPT_HEBREW: + { + static const sal_Unicode aHebr[] = { + 0x05D0, 0x05B8, 0x05DC, 0x05B6, 0x05E3, 0x05BE, 0x05D1, 0x05B5, + 0x05BC, 0x05D9, 0x05EA, 0x0020, 0x05E2, 0x05B4, 0x05D1, 0x05B0, + 0x05E8, 0x05B4, 0x05D9 + }; + sSampleText = OUString(aHebr, SAL_N_ELEMENTS(aHebr)); + break; + } + case USCRIPT_ARABIC: + { + static const sal_Unicode aArab[] = { + 0x0623, 0x0628, 0x062C, 0x062F, 0x064A, 0x0629, 0x0020, 0x0639, + 0x0631, 0x0628, 0x064A, 0x0629 + }; + sSampleText = OUString(aArab, SAL_N_ELEMENTS(aArab)); + break; + } + case USCRIPT_ARMENIAN: + { + static const sal_Unicode aArmenian[] = { + 0x0561, 0x0575, 0x0562, 0x0578, 0x0582, 0x0562, 0x0565, + 0x0576 + }; + sSampleText = OUString(aArmenian, SAL_N_ELEMENTS(aArmenian)); + break; + } + case USCRIPT_DEVANAGARI: + { + static const sal_Unicode aDeva[] = { + 0x0926, 0x0947, 0x0935, 0x0928, 0x093E, 0x0917, 0x0930, 0x0940 + }; + sSampleText = OUString(aDeva, SAL_N_ELEMENTS(aDeva)); + break; + } + case USCRIPT_BENGALI: + { + static const sal_Unicode aBeng[] = { + 0x09AC, 0x09BE, 0x0982, 0x09B2, 0x09BE, 0x0020, 0x09B2, 0x09BF, + 0x09AA, 0x09BF + }; + sSampleText = OUString(aBeng, SAL_N_ELEMENTS(aBeng)); + break; + } + case USCRIPT_GURMUKHI: + { + static const sal_Unicode aGuru[] = { + 0x0A17, 0x0A41, 0x0A30, 0x0A2E, 0x0A41, 0x0A16, 0x0A40 + }; + sSampleText = OUString(aGuru, SAL_N_ELEMENTS(aGuru)); + break; + } + case USCRIPT_GUJARATI: + { + static const sal_Unicode aGujr[] = { + 0x0A97, 0x0AC1, 0x0A9C, 0x0AB0, 0x0ABE, 0x0AA4, 0x0aC0, 0x0020, + 0x0AB2, 0x0ABF, 0x0AAA, 0x0ABF + }; + sSampleText = OUString(aGujr, SAL_N_ELEMENTS(aGujr)); + break; + } + case USCRIPT_ORIYA: + { + static const sal_Unicode aOrya[] = { + 0x0B09, 0x0B24, 0x0B4D, 0x0B15, 0x0B33, 0x0020, 0x0B32, 0x0B3F, + 0x0B2A, 0x0B3F + }; + sSampleText = OUString(aOrya, SAL_N_ELEMENTS(aOrya)); + break; + } + case USCRIPT_TAMIL: + { + static const sal_Unicode aTaml[] = { + 0x0B85, 0x0BB0, 0x0BBF, 0x0B9A, 0x0BCD, 0x0B9A, 0x0BC1, 0x0BB5, + 0x0B9F, 0x0BBF + }; + sSampleText = OUString(aTaml, SAL_N_ELEMENTS(aTaml)); + break; + } + case USCRIPT_TELUGU: + { + static const sal_Unicode aTelu[] = { + 0x0C24, 0x0C46, 0x0C32, 0x0C41, 0x0C17, 0x0C41 + }; + sSampleText = OUString(aTelu, SAL_N_ELEMENTS(aTelu)); + break; + } + case USCRIPT_KANNADA: + { + static const sal_Unicode aKnda[] = { + 0x0C95, 0x0CA8, 0x0CCD, 0x0CA8, 0x0CA1, 0x0020, 0x0CB2, 0x0CBF, + 0x0CAA, 0x0CBF + }; + sSampleText = OUString(aKnda, SAL_N_ELEMENTS(aKnda)); + break; + } + case USCRIPT_MALAYALAM: + { + static const sal_Unicode aMlym[] = { + 0x0D2E, 0x0D32, 0x0D2F, 0x0D3E, 0x0D33, 0x0D32, 0x0D3F, 0x0D2A, + 0x0D3F + }; + sSampleText = OUString(aMlym, SAL_N_ELEMENTS(aMlym)); + break; + } + case USCRIPT_THAI: + { + static const sal_Unicode aThai[] = { + 0x0E2D, 0x0E31, 0x0E01, 0x0E29, 0x0E23, 0x0E44, 0x0E17, 0x0E22 + }; + sSampleText = OUString(aThai, SAL_N_ELEMENTS(aThai)); + break; + } + case USCRIPT_LAO: + { + static const sal_Unicode aLao[] = { + 0x0EAD, 0x0EB1, 0x0E81, 0x0EAA, 0x0EAD, 0x0E99, 0x0EA5, 0x0EB2, + 0x0EA7 + }; + sSampleText = OUString(aLao, SAL_N_ELEMENTS(aLao)); + break; + } + case USCRIPT_GEORGIAN: + { + static const sal_Unicode aGeorgian[] = { + 0x10D3, 0x10D0, 0x10DB, 0x10EC, 0x10D4, 0x10E0, 0x10DA, 0x10DD, + 0x10D1, 0x10D0 + }; + sSampleText = OUString(aGeorgian, SAL_N_ELEMENTS(aGeorgian)); + break; + } + case USCRIPT_HANGUL: + case USCRIPT_KOREAN: + { + static const sal_Unicode aHang[] = { + 0xD55C, 0xAE00 + }; + sSampleText = OUString(aHang, SAL_N_ELEMENTS(aHang)); + break; + } + case USCRIPT_TIBETAN: + { + static const sal_Unicode aTibt[] = { + 0x0F51, 0x0F56, 0x0F74, 0x0F0B, 0x0F45, 0x0F53, 0x0F0B + }; + sSampleText = OUString(aTibt, SAL_N_ELEMENTS(aTibt)); + break; + } + case USCRIPT_SYRIAC: + { + static const sal_Unicode aSyri[] = { + 0x0723, 0x071B, 0x072A, 0x0722, 0x0713, 0x0720, 0x0710 + }; + sSampleText = OUString(aSyri, SAL_N_ELEMENTS(aSyri)); + break; + } + case USCRIPT_THAANA: + { + static const sal_Unicode aThaa[] = { + 0x078C, 0x07A7, 0x0782, 0x07A6 + }; + sSampleText = OUString(aThaa, SAL_N_ELEMENTS(aThaa)); + break; + } + case USCRIPT_SINHALA: + { + static const sal_Unicode aSinh[] = { + 0x0DC1, 0x0DD4, 0x0DAF, 0x0DCA, 0x0DB0, 0x0020, 0x0DC3, 0x0DD2, + 0x0D82, 0x0DC4, 0x0DBD + }; + sSampleText = OUString(aSinh, SAL_N_ELEMENTS(aSinh)); + break; + } + case USCRIPT_MYANMAR: + { + static const sal_Unicode aMymr[] = { + 0x1019, 0x103C, 0x1014, 0x103A, 0x1019, 0x102C, 0x1021, 0x1000, + 0x1039, 0x1001, 0x101B, 0x102C + }; + sSampleText = OUString(aMymr, SAL_N_ELEMENTS(aMymr)); + break; + } + case USCRIPT_ETHIOPIC: + { + static const sal_Unicode aEthi[] = { + 0x130D, 0x12D5, 0x12DD + }; + sSampleText = OUString(aEthi, SAL_N_ELEMENTS(aEthi)); + break; + } + case USCRIPT_CHEROKEE: + { + static const sal_Unicode aCher[] = { + 0x13D7, 0x13AA, 0x13EA, 0x13B6, 0x13D9, 0x13D7 + }; + sSampleText = OUString(aCher, SAL_N_ELEMENTS(aCher)); + break; + } + case USCRIPT_KHMER: + { + static const sal_Unicode aKhmr[] = { + 0x17A2, 0x1780, 0x17D2, 0x1781, 0x179A, 0x1780, 0x17D2, 0x179A, + 0x1798, 0x1781, 0x17C1, 0x1798, 0x179A, 0x1797, 0x17B6, 0x179F, + 0x17B6 + }; + sSampleText = OUString(aKhmr, SAL_N_ELEMENTS(aKhmr)); + break; + } + case USCRIPT_MONGOLIAN: + { + static const sal_Unicode aMongolian[] = { + 0x182A, 0x1822, 0x1834, 0x1822, 0x182D, 0x180C + }; + sSampleText = OUString(aMongolian, SAL_N_ELEMENTS(aMongolian)); + break; + } + case USCRIPT_TAGALOG: + { + static const sal_Unicode aTagalog[] = { + 0x170A, 0x170A, 0x170C, 0x1712 + }; + sSampleText = OUString(aTagalog, SAL_N_ELEMENTS(aTagalog)); + break; + } + case USCRIPT_NEW_TAI_LUE: + { + static const sal_Unicode aTalu[] = { + 0x1991, 0x19BA, 0x199F, 0x19B9, 0x19C9 + }; + sSampleText = OUString(aTalu, SAL_N_ELEMENTS(aTalu)); + break; + } + case USCRIPT_TRADITIONAL_HAN: + { + static const sal_Unicode aHant[] = { + 0x7E41 + }; + sSampleText = OUString(aHant, SAL_N_ELEMENTS(aHant)); + break; + } + case USCRIPT_SIMPLIFIED_HAN: + { + static const sal_Unicode aHans[] = { + 0x7B80 + }; + sSampleText = OUString(aHans, SAL_N_ELEMENTS(aHans)); + break; + } + case USCRIPT_HAN: + { + static const sal_Unicode aSimplifiedAndTraditionalChinese[] = { + 0x7B80, 0x7E41 + }; + sSampleText = OUString(aSimplifiedAndTraditionalChinese, + SAL_N_ELEMENTS(aSimplifiedAndTraditionalChinese)); + break; + } + case USCRIPT_JAPANESE: + { + static const sal_Unicode aJpan[] = { + 0x65E5, 0x672C, 0x8A9E + }; + sSampleText = OUString(aJpan, SAL_N_ELEMENTS(aJpan)); + break; + } + case USCRIPT_YI: + { + static const sal_Unicode aYiii[] = { + 0xA188, 0xA320, 0xA071, 0xA0B7 + }; + sSampleText = OUString(aYiii, SAL_N_ELEMENTS(aYiii)); + break; + } + case USCRIPT_PHAGS_PA: + { + static const sal_Unicode aPhag[] = { + 0xA84F, 0xA861, 0xA843, 0x0020, 0xA863, 0xA861, 0xA859, 0x0020, + 0xA850, 0xA85C, 0xA85E + }; + sSampleText = OUString(aPhag, SAL_N_ELEMENTS(aPhag)); + break; + } + case USCRIPT_TAI_LE: + { + static const sal_Unicode aTale[] = { + 0x1956, 0x196D, 0x1970, 0x1956, 0x196C, 0x1973, 0x1951, 0x1968, + 0x1952, 0x1970 + }; + sSampleText = OUString(aTale, SAL_N_ELEMENTS(aTale)); + break; + } + case USCRIPT_LATIN: + sSampleText = "Lorem ipsum"; + break; + default: + break; + } + return sSampleText; +} + +static OUString makeRepresentativeTextForScript(UScriptCode eScript) +{ + OUString sSampleText; + switch (eScript) + { + case USCRIPT_TRADITIONAL_HAN: + case USCRIPT_SIMPLIFIED_HAN: + case USCRIPT_HAN: + { + //Three Character Classic + static const sal_Unicode aZh[] = { + 0x4EBA, 0x4E4B, 0x521D, 0x0020, 0x6027, 0x672C, 0x5584 + }; + sSampleText = OUString(aZh, SAL_N_ELEMENTS(aZh)); + break; + } + case USCRIPT_JAPANESE: + { + //'Beautiful Japanese' + static const sal_Unicode aJa[] = { + 0x7F8E, 0x3057, 0x3044, 0x65E5, 0x672C, 0x8A9E + }; + sSampleText = OUString(aJa, SAL_N_ELEMENTS(aJa)); + break; + } + case USCRIPT_KOREAN: + case USCRIPT_HANGUL: + { + //The essential condition for... + static const sal_Unicode aKo[] = { + 0xD0A4, 0xC2A4, 0xC758, 0x0020, 0xACE0, 0xC720, 0xC870, + 0xAC74, 0xC740 + }; + sSampleText = OUString(aKo, SAL_N_ELEMENTS(aKo)); + break; + } + default: + break; + } + + if (sSampleText.isEmpty()) + sSampleText = makeShortRepresentativeTextForScript(eScript); + return sSampleText; +} + +OUString makeShortMinimalTextForScript(UScriptCode eScript) +{ + OUString sSampleText; + switch (eScript) + { + case USCRIPT_GREEK: + { + static const sal_Unicode aGrek[] = { + 0x0391, 0x0392 + }; + sSampleText = OUString(aGrek, SAL_N_ELEMENTS(aGrek)); + break; + } + case USCRIPT_HEBREW: + { + static const sal_Unicode aHebr[] = { + 0x05D0, 0x05D1 + }; + sSampleText = OUString(aHebr, SAL_N_ELEMENTS(aHebr)); + break; + } + default: + break; + } + return sSampleText; +} + +static 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 makeShortRepresentativeTextForScript when we don't +//have suitable strings +static OUString makeRepresentativeTextForLanguage(LanguageType eLang) +{ + OUString sRet; + LanguageType pri = primary(eLang); + if( pri == primary(LANGUAGE_ARMENIAN) ) + sRet = makeRepresentativeTextForScript(USCRIPT_ARMENIAN); + else if( pri == primary(LANGUAGE_CHINESE) ) + sRet = makeRepresentativeTextForScript(USCRIPT_HAN); + else if( pri == primary(LANGUAGE_GREEK) ) + sRet = makeRepresentativeTextForScript(USCRIPT_GREEK); + else if( pri.anyOf( + primary(LANGUAGE_HEBREW), + primary(LANGUAGE_YIDDISH)) ) + sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW); + else if( pri == primary(LANGUAGE_ARABIC_SAUDI_ARABIA) ) + sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC); + else if( pri == primary(LANGUAGE_HINDI) ) + sRet = makeRepresentativeTextForScript(USCRIPT_DEVANAGARI); + else if( pri == primary(LANGUAGE_ASSAMESE) ) + { + static const sal_Unicode aAs[] = { + 0x0985, 0x09B8, 0x09AE, 0x09C0, 0x09AF, 0x09BC, 0x09BE, + 0x0020, 0x0986, 0x0996, 0x09F0 + }; + sRet = OUString(aAs, SAL_N_ELEMENTS(aAs)); + } + else if( pri == primary(LANGUAGE_BENGALI) ) + sRet = makeRepresentativeTextForScript(USCRIPT_BENGALI); + else if( pri == primary(LANGUAGE_PUNJABI) ) + sRet = makeRepresentativeTextForScript(USCRIPT_GURMUKHI); + else if( pri == primary(LANGUAGE_GUJARATI) ) + sRet = makeRepresentativeTextForScript(USCRIPT_GUJARATI); + else if( pri == primary(LANGUAGE_ODIA) ) + sRet = makeRepresentativeTextForScript(USCRIPT_ORIYA); + else if( pri == primary(LANGUAGE_TAMIL) ) + sRet = makeRepresentativeTextForScript(USCRIPT_TAMIL); + else if( pri == primary(LANGUAGE_TELUGU) ) + sRet = makeRepresentativeTextForScript(USCRIPT_TELUGU); + else if( pri == primary(LANGUAGE_KANNADA) ) + sRet = makeRepresentativeTextForScript(USCRIPT_KANNADA); + else if( pri == primary(LANGUAGE_MALAYALAM) ) + sRet = makeRepresentativeTextForScript(USCRIPT_MALAYALAM); + else if( pri == primary(LANGUAGE_THAI) ) + sRet = makeRepresentativeTextForScript(USCRIPT_THAI); + else if( pri == primary(LANGUAGE_LAO) ) + sRet = makeRepresentativeTextForScript(USCRIPT_LAO); + else if( pri == primary(LANGUAGE_GEORGIAN) ) + sRet = makeRepresentativeTextForScript(USCRIPT_GEORGIAN); + else if( pri == primary(LANGUAGE_KOREAN) ) + sRet = makeRepresentativeTextForScript(USCRIPT_KOREAN); + else if( pri == primary(LANGUAGE_TIBETAN) ) + sRet = makeRepresentativeTextForScript(USCRIPT_TIBETAN); + else if( pri == primary(LANGUAGE_SYRIAC) ) + sRet = makeRepresentativeTextForScript(USCRIPT_SYRIAC); + else if( pri == primary(LANGUAGE_SINHALESE_SRI_LANKA) ) + sRet = makeRepresentativeTextForScript(USCRIPT_SINHALA); + else if( pri == primary(LANGUAGE_BURMESE) ) + sRet = makeRepresentativeTextForScript(USCRIPT_MYANMAR); + else if( pri == primary(LANGUAGE_AMHARIC_ETHIOPIA) ) + sRet = makeRepresentativeTextForScript(USCRIPT_ETHIOPIC); + else if( pri == primary(LANGUAGE_CHEROKEE_UNITED_STATES) ) + sRet = makeRepresentativeTextForScript(USCRIPT_CHEROKEE); + else if( pri == primary(LANGUAGE_KHMER) ) + sRet = makeRepresentativeTextForScript(USCRIPT_KHMER); + else if( pri == primary(LANGUAGE_MONGOLIAN_MONGOLIAN_LSO) ) + { + if (eLang.anyOf( + LANGUAGE_MONGOLIAN_MONGOLIAN_MONGOLIA, + LANGUAGE_MONGOLIAN_MONGOLIAN_CHINA, + LANGUAGE_MONGOLIAN_MONGOLIAN_LSO)) + sRet = makeRepresentativeTextForScript(USCRIPT_MONGOLIAN); + } + else if( pri == primary(LANGUAGE_JAPANESE) ) + sRet = makeRepresentativeTextForScript(USCRIPT_JAPANESE); + else if( pri == primary(LANGUAGE_YI) ) + sRet = makeRepresentativeTextForScript(USCRIPT_YI); + else if( pri == primary(LANGUAGE_GAELIC_IRELAND) ) + { + static const sal_Unicode aGa[] = { + 'T', 0x00E9, 'a', 'c', 's', ' ', 'S', 'a', 'm', 'p', 'l', 'a', 'c', 'h' + }; + sRet = OUString(aGa, SAL_N_ELEMENTS(aGa)); + } + + return sRet; +} + +namespace +{ +#if OSL_DEBUG_LEVEL > 0 + void lcl_dump_unicode_coverage(const std::optional<std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM>> &roIn) + { + if (!roIn) + { + SAL_INFO("svtools", "<NOTHING>"); + return; + } + auto & rIn(*roIn); + if (rIn.none()) + { + SAL_INFO("svtools", "<NONE>"); + return; + } + if (rIn[vcl::UnicodeCoverage::BASIC_LATIN]) + SAL_INFO("svtools", "BASIC_LATIN"); + if (rIn[vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT]) + SAL_INFO("svtools", "LATIN_1_SUPPLEMENT"); + if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_A]) + SAL_INFO("svtools", "LATIN_EXTENDED_A"); + if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_B]) + SAL_INFO("svtools", "LATIN_EXTENDED_B"); + if (rIn[vcl::UnicodeCoverage::IPA_EXTENSIONS]) + SAL_INFO("svtools", "IPA_EXTENSIONS"); + if (rIn[vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS]) + SAL_INFO("svtools", "SPACING_MODIFIER_LETTERS"); + if (rIn[vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS]) + SAL_INFO("svtools", "COMBINING_DIACRITICAL_MARKS"); + if (rIn[vcl::UnicodeCoverage::GREEK_AND_COPTIC]) + SAL_INFO("svtools", "GREEK_AND_COPTIC"); + if (rIn[vcl::UnicodeCoverage::COPTIC]) + SAL_INFO("svtools", "COPTIC"); + if (rIn[vcl::UnicodeCoverage::CYRILLIC]) + SAL_INFO("svtools", "CYRILLIC"); + if (rIn[vcl::UnicodeCoverage::ARMENIAN]) + SAL_INFO("svtools", "ARMENIAN"); + if (rIn[vcl::UnicodeCoverage::HEBREW]) + SAL_INFO("svtools", "HEBREW"); + if (rIn[vcl::UnicodeCoverage::VAI]) + SAL_INFO("svtools", "VAI"); + if (rIn[vcl::UnicodeCoverage::ARABIC]) + SAL_INFO("svtools", "ARABIC"); + if (rIn[vcl::UnicodeCoverage::NKO]) + SAL_INFO("svtools", "NKO"); + if (rIn[vcl::UnicodeCoverage::DEVANAGARI]) + SAL_INFO("svtools", "DEVANAGARI"); + if (rIn[vcl::UnicodeCoverage::BENGALI]) + SAL_INFO("svtools", "BENGALI"); + if (rIn[vcl::UnicodeCoverage::GURMUKHI]) + SAL_INFO("svtools", "GURMUKHI"); + if (rIn[vcl::UnicodeCoverage::GUJARATI]) + SAL_INFO("svtools", "GUJARATI"); + if (rIn[vcl::UnicodeCoverage::ODIA]) + SAL_INFO("svtools", "ODIA"); + if (rIn[vcl::UnicodeCoverage::TAMIL]) + SAL_INFO("svtools", "TAMIL"); + if (rIn[vcl::UnicodeCoverage::TELUGU]) + SAL_INFO("svtools", "TELUGU"); + if (rIn[vcl::UnicodeCoverage::KANNADA]) + SAL_INFO("svtools", "KANNADA"); + if (rIn[vcl::UnicodeCoverage::MALAYALAM]) + SAL_INFO("svtools", "MALAYALAM"); + if (rIn[vcl::UnicodeCoverage::THAI]) + SAL_INFO("svtools", "THAI"); + if (rIn[vcl::UnicodeCoverage::LAO]) + SAL_INFO("svtools", "LAO"); + if (rIn[vcl::UnicodeCoverage::GEORGIAN]) + SAL_INFO("svtools", "GEORGIAN"); + if (rIn[vcl::UnicodeCoverage::BALINESE]) + SAL_INFO("svtools", "BALINESE"); + if (rIn[vcl::UnicodeCoverage::HANGUL_JAMO]) + SAL_INFO("svtools", "HANGUL_JAMO"); + if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL]) + SAL_INFO("svtools", "LATIN_EXTENDED_ADDITIONAL"); + if (rIn[vcl::UnicodeCoverage::GREEK_EXTENDED]) + SAL_INFO("svtools", "GREEK_EXTENDED"); + if (rIn[vcl::UnicodeCoverage::GENERAL_PUNCTUATION]) + SAL_INFO("svtools", "GENERAL_PUNCTUATION"); + if (rIn[vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS]) + SAL_INFO("svtools", "SUPERSCRIPTS_AND_SUBSCRIPTS"); + if (rIn[vcl::UnicodeCoverage::CURRENCY_SYMBOLS]) + SAL_INFO("svtools", "CURRENCY_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS]) + SAL_INFO("svtools", "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS]) + SAL_INFO("svtools", "LETTERLIKE_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::NUMBER_FORMS]) + SAL_INFO("svtools", "NUMBER_FORMS"); + if (rIn[vcl::UnicodeCoverage::ARROWS]) + SAL_INFO("svtools", "ARROWS"); + if (rIn[vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS]) + SAL_INFO("svtools", "MATHEMATICAL_OPERATORS"); + if (rIn[vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL]) + SAL_INFO("svtools", "MISCELLANEOUS_TECHNICAL"); + if (rIn[vcl::UnicodeCoverage::CONTROL_PICTURES]) + SAL_INFO("svtools", "CONTROL_PICTURES"); + if (rIn[vcl::UnicodeCoverage::OPTICAL_CHARACTER_RECOGNITION]) + SAL_INFO("svtools", "OPTICAL_CHARACTER_RECOGNITION"); + if (rIn[vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS]) + SAL_INFO("svtools", "ENCLOSED_ALPHANUMERICS"); + if (rIn[vcl::UnicodeCoverage::BOX_DRAWING]) + SAL_INFO("svtools", "BOX_DRAWING"); + if (rIn[vcl::UnicodeCoverage::BLOCK_ELEMENTS]) + SAL_INFO("svtools", "BLOCK_ELEMENTS"); + if (rIn[vcl::UnicodeCoverage::GEOMETRIC_SHAPES]) + SAL_INFO("svtools", "GEOMETRIC_SHAPES"); + if (rIn[vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS]) + SAL_INFO("svtools", "MISCELLANEOUS_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::DINGBATS]) + SAL_INFO("svtools", "DINGBATS"); + if (rIn[vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION]) + SAL_INFO("svtools", "CJK_SYMBOLS_AND_PUNCTUATION"); + if (rIn[vcl::UnicodeCoverage::HIRAGANA]) + SAL_INFO("svtools", "HIRAGANA"); + if (rIn[vcl::UnicodeCoverage::KATAKANA]) + SAL_INFO("svtools", "KATAKANA"); + if (rIn[vcl::UnicodeCoverage::BOPOMOFO]) + SAL_INFO("svtools", "BOPOMOFO"); + if (rIn[vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO]) + SAL_INFO("svtools", "HANGUL_COMPATIBILITY_JAMO"); + if (rIn[vcl::UnicodeCoverage::PHAGS_PA]) + SAL_INFO("svtools", "PHAGS_PA"); + if (rIn[vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS]) + SAL_INFO("svtools", "ENCLOSED_CJK_LETTERS_AND_MONTHS"); + if (rIn[vcl::UnicodeCoverage::CJK_COMPATIBILITY]) + SAL_INFO("svtools", "CJK_COMPATIBILITY"); + if (rIn[vcl::UnicodeCoverage::HANGUL_SYLLABLES]) + SAL_INFO("svtools", "HANGUL_SYLLABLES"); + if (rIn[vcl::UnicodeCoverage::NONPLANE_0]) + SAL_INFO("svtools", "NONPLANE_0"); + if (rIn[vcl::UnicodeCoverage::PHOENICIAN]) + SAL_INFO("svtools", "PHOENICIAN"); + if (rIn[vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS]) + SAL_INFO("svtools", "CJK_UNIFIED_IDEOGRAPHS"); + if (rIn[vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0]) + SAL_INFO("svtools", "PRIVATE_USE_AREA_PLANE_0"); + if (rIn[vcl::UnicodeCoverage::CJK_STROKES]) + SAL_INFO("svtools", "CJK_STROKES"); + if (rIn[vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS]) + SAL_INFO("svtools", "ALPHABETIC_PRESENTATION_FORMS"); + if (rIn[vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A]) + SAL_INFO("svtools", "ARABIC_PRESENTATION_FORMS_A"); + if (rIn[vcl::UnicodeCoverage::COMBINING_HALF_MARKS]) + SAL_INFO("svtools", "COMBINING_HALF_MARKS"); + if (rIn[vcl::UnicodeCoverage::VERTICAL_FORMS]) + SAL_INFO("svtools", "VERTICAL_FORMS"); + if (rIn[vcl::UnicodeCoverage::SMALL_FORM_VARIANTS]) + SAL_INFO("svtools", "SMALL_FORM_VARIANTS"); + if (rIn[vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B]) + SAL_INFO("svtools", "ARABIC_PRESENTATION_FORMS_B"); + if (rIn[vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS]) + SAL_INFO("svtools", "HALFWIDTH_AND_FULLWIDTH_FORMS"); + if (rIn[vcl::UnicodeCoverage::SPECIALS]) + SAL_INFO("svtools", "SPECIALS"); + if (rIn[vcl::UnicodeCoverage::TIBETAN]) + SAL_INFO("svtools", "TIBETAN"); + if (rIn[vcl::UnicodeCoverage::SYRIAC]) + SAL_INFO("svtools", "SYRIAC"); + if (rIn[vcl::UnicodeCoverage::THAANA]) + SAL_INFO("svtools", "THAANA"); + if (rIn[vcl::UnicodeCoverage::SINHALA]) + SAL_INFO("svtools", "SINHALA"); + if (rIn[vcl::UnicodeCoverage::MYANMAR]) + SAL_INFO("svtools", "MYANMAR"); + if (rIn[vcl::UnicodeCoverage::ETHIOPIC]) + SAL_INFO("svtools", "ETHIOPIC"); + if (rIn[vcl::UnicodeCoverage::CHEROKEE]) + SAL_INFO("svtools", "CHEROKEE"); + if (rIn[vcl::UnicodeCoverage::UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS]) + SAL_INFO("svtools", "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS"); + if (rIn[vcl::UnicodeCoverage::OGHAM]) + SAL_INFO("svtools", "OGHAM"); + if (rIn[vcl::UnicodeCoverage::RUNIC]) + SAL_INFO("svtools", "RUNIC"); + if (rIn[vcl::UnicodeCoverage::KHMER]) + SAL_INFO("svtools", "KHMER"); + if (rIn[vcl::UnicodeCoverage::MONGOLIAN]) + SAL_INFO("svtools", "MONGOLIAN"); + if (rIn[vcl::UnicodeCoverage::BRAILLE_PATTERNS]) + SAL_INFO("svtools", "BRAILLE_PATTERNS"); + if (rIn[vcl::UnicodeCoverage::YI_SYLLABLES]) + SAL_INFO("svtools", "YI_SYLLABLES"); + if (rIn[vcl::UnicodeCoverage::TAGALOG]) + SAL_INFO("svtools", "TAGALOG"); + if (rIn[vcl::UnicodeCoverage::OLD_ITALIC]) + SAL_INFO("svtools", "OLD_ITALIC"); + if (rIn[vcl::UnicodeCoverage::GOTHIC]) + SAL_INFO("svtools", "GOTHIC"); + if (rIn[vcl::UnicodeCoverage::DESERET]) + SAL_INFO("svtools", "DESERET"); + if (rIn[vcl::UnicodeCoverage::BYZANTINE_MUSICAL_SYMBOLS]) + SAL_INFO("svtools", "BYZANTINE_MUSICAL_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS]) + SAL_INFO("svtools", "MATHEMATICAL_ALPHANUMERIC_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15]) + SAL_INFO("svtools", "PRIVATE_USE_PLANE_15"); + if (rIn[vcl::UnicodeCoverage::VARIATION_SELECTORS]) + SAL_INFO("svtools", "VARIATION_SELECTORS"); + if (rIn[vcl::UnicodeCoverage::TAGS]) + SAL_INFO("svtools", "TAGS"); + if (rIn[vcl::UnicodeCoverage::LIMBU]) + SAL_INFO("svtools", "LIMBU"); + if (rIn[vcl::UnicodeCoverage::TAI_LE]) + SAL_INFO("svtools", "TAI_LE"); + if (rIn[vcl::UnicodeCoverage::NEW_TAI_LUE]) + SAL_INFO("svtools", "NEW_TAI_LUE"); + if (rIn[vcl::UnicodeCoverage::BUGINESE]) + SAL_INFO("svtools", "BUGINESE"); + if (rIn[vcl::UnicodeCoverage::GLAGOLITIC]) + SAL_INFO("svtools", "GLAGOLITIC"); + if (rIn[vcl::UnicodeCoverage::TIFINAGH]) + SAL_INFO("svtools", "TIFINAGH"); + if (rIn[vcl::UnicodeCoverage::YIJING_HEXAGRAM_SYMBOLS]) + SAL_INFO("svtools", "YIJING_HEXAGRAM_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::SYLOTI_NAGRI]) + SAL_INFO("svtools", "SYLOTI_NAGRI"); + if (rIn[vcl::UnicodeCoverage::LINEAR_B_SYLLABARY]) + SAL_INFO("svtools", "LINEAR_B_SYLLABARY"); + if (rIn[vcl::UnicodeCoverage::ANCIENT_GREEK_NUMBERS]) + SAL_INFO("svtools", "ANCIENT_GREEK_NUMBERS"); + if (rIn[vcl::UnicodeCoverage::UGARITIC]) + SAL_INFO("svtools", "UGARITIC"); + if (rIn[vcl::UnicodeCoverage::OLD_PERSIAN]) + SAL_INFO("svtools", "OLD_PERSIAN"); + if (rIn[vcl::UnicodeCoverage::SHAVIAN]) + SAL_INFO("svtools", "SHAVIAN"); + if (rIn[vcl::UnicodeCoverage::OSMANYA]) + SAL_INFO("svtools", "OSMANYA"); + if (rIn[vcl::UnicodeCoverage::CYPRIOT_SYLLABARY]) + SAL_INFO("svtools", "CYPRIOT_SYLLABARY"); + if (rIn[vcl::UnicodeCoverage::KHAROSHTHI]) + SAL_INFO("svtools", "KHAROSHTHI"); + if (rIn[vcl::UnicodeCoverage::TAI_XUAN_JING_SYMBOLS]) + SAL_INFO("svtools", "TAI_XUAN_JING_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::CUNEIFORM]) + SAL_INFO("svtools", "CUNEIFORM"); + if (rIn[vcl::UnicodeCoverage::COUNTING_ROD_NUMERALS]) + SAL_INFO("svtools", "COUNTING_ROD_NUMERALS"); + if (rIn[vcl::UnicodeCoverage::SUNDANESE]) + SAL_INFO("svtools", "SUNDANESE"); + if (rIn[vcl::UnicodeCoverage::LEPCHA]) + SAL_INFO("svtools", "LEPCHA"); + if (rIn[vcl::UnicodeCoverage::OL_CHIKI]) + SAL_INFO("svtools", "OL_CHIKI"); + if (rIn[vcl::UnicodeCoverage::SAURASHTRA]) + SAL_INFO("svtools", "SAURASHTRA"); + if (rIn[vcl::UnicodeCoverage::KAYAH_LI]) + SAL_INFO("svtools", "KAYAH_LI"); + if (rIn[vcl::UnicodeCoverage::REJANG]) + SAL_INFO("svtools", "REJANG"); + if (rIn[vcl::UnicodeCoverage::CHAM]) + SAL_INFO("svtools", "CHAM"); + if (rIn[vcl::UnicodeCoverage::ANCIENT_SYMBOLS]) + SAL_INFO("svtools", "ANCIENT_SYMBOLS"); + if (rIn[vcl::UnicodeCoverage::PHAISTOS_DISC]) + SAL_INFO("svtools", "PHAISTOS_DISC"); + if (rIn[vcl::UnicodeCoverage::CARIAN]) + SAL_INFO("svtools", "CARIAN"); + if (rIn[vcl::UnicodeCoverage::DOMINO_TILES]) + SAL_INFO("svtools", "DOMINO_TILES"); + if (rIn[vcl::UnicodeCoverage::RESERVED1]) + SAL_INFO("svtools", "RESERVED1"); + if (rIn[vcl::UnicodeCoverage::RESERVED2]) + SAL_INFO("svtools", "RESERVED2"); + if (rIn[vcl::UnicodeCoverage::RESERVED3]) + SAL_INFO("svtools", "RESERVED3"); + if (rIn[vcl::UnicodeCoverage::RESERVED4]) + SAL_INFO("svtools", "RESERVED4"); + if (rIn[vcl::UnicodeCoverage::RESERVED5]) + SAL_INFO("svtools", "RESERVED5"); + } + + void lcl_dump_codepage_coverage(const std::optional<std::bitset<vcl::CodePageCoverage::MAX_CP_ENUM>> &roIn) + { + if (!roIn) + { + SAL_INFO("svtools", "<NOTHING>"); + return; + } + auto & rIn(*roIn); + if (rIn.none()) + { + SAL_INFO("svtools", "<NONE>"); + return; + } + if (rIn[vcl::CodePageCoverage::CP1252]) + SAL_INFO("svtools", "CP1252"); + if (rIn[vcl::CodePageCoverage::CP1250]) + SAL_INFO("svtools", "CP1250"); + if (rIn[vcl::CodePageCoverage::CP1251]) + SAL_INFO("svtools", "CP1251"); + if (rIn[vcl::CodePageCoverage::CP1253]) + SAL_INFO("svtools", "CP1253"); + if (rIn[vcl::CodePageCoverage::CP1254]) + SAL_INFO("svtools", "CP1254"); + if (rIn[vcl::CodePageCoverage::CP1255]) + SAL_INFO("svtools", "CP1255"); + if (rIn[vcl::CodePageCoverage::CP1256]) + SAL_INFO("svtools", "CP1256"); + if (rIn[vcl::CodePageCoverage::CP1257]) + SAL_INFO("svtools", "CP1257"); + if (rIn[vcl::CodePageCoverage::CP1258]) + SAL_INFO("svtools", "CP1258"); + if (rIn[vcl::CodePageCoverage::CP874]) + SAL_INFO("svtools", "CP874"); + if (rIn[vcl::CodePageCoverage::CP932]) + SAL_INFO("svtools", "CP932"); + if (rIn[vcl::CodePageCoverage::CP936]) + SAL_INFO("svtools", "CP936"); + if (rIn[vcl::CodePageCoverage::CP949]) + SAL_INFO("svtools", "CP949"); + if (rIn[vcl::CodePageCoverage::CP950]) + SAL_INFO("svtools", "CP950"); + if (rIn[vcl::CodePageCoverage::CP1361]) + SAL_INFO("svtools", "CP1361"); + if (rIn[vcl::CodePageCoverage::CP869]) + SAL_INFO("svtools", "CP869"); + if (rIn[vcl::CodePageCoverage::CP866]) + SAL_INFO("svtools", "CP866"); + if (rIn[vcl::CodePageCoverage::CP865]) + SAL_INFO("svtools", "CP865"); + if (rIn[vcl::CodePageCoverage::CP864]) + SAL_INFO("svtools", "CP864"); + if (rIn[vcl::CodePageCoverage::CP863]) + SAL_INFO("svtools", "CP863"); + if (rIn[vcl::CodePageCoverage::CP862]) + SAL_INFO("svtools", "CP862"); + if (rIn[vcl::CodePageCoverage::CP861]) + SAL_INFO("svtools", "CP861"); + if (rIn[vcl::CodePageCoverage::CP860]) + SAL_INFO("svtools", "CP860"); + if (rIn[vcl::CodePageCoverage::CP857]) + SAL_INFO("svtools", "CP857"); + if (rIn[vcl::CodePageCoverage::CP855]) + SAL_INFO("svtools", "CP855"); + if (rIn[vcl::CodePageCoverage::CP852]) + SAL_INFO("svtools", "CP852"); + if (rIn[vcl::CodePageCoverage::CP775]) + SAL_INFO("svtools", "CP775"); + if (rIn[vcl::CodePageCoverage::CP737]) + SAL_INFO("svtools", "CP737"); + if (rIn[vcl::CodePageCoverage::CP780]) + SAL_INFO("svtools", "CP780"); + if (rIn[vcl::CodePageCoverage::CP850]) + SAL_INFO("svtools", "CP850"); + if (rIn[vcl::CodePageCoverage::CP437]) + SAL_INFO("svtools", "CP437"); + } +#endif + + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> getMaskByScriptType(sal_Int16 nScriptType) + { + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> aMask; + 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 + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getLatinMask() + { + static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::LATIN)); + return s_Mask; + } + + //false for all bits considered "Asian" by LibreOffice + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getCJKMask() + { + static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::ASIAN)); + return s_Mask; + } + + //false for all bits considered "Complex" by LibreOffice + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getCTLMask() + { + static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::COMPLEX)); + return s_Mask; + } + + //false for all bits considered "WEAK" by LibreOffice + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getWeakMask() + { + static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::WEAK)); + return s_Mask; + } + + //Nearly every font supports some basic Latin + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> getCommonLatnSubsetMask() + { + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> aMask; + 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; + } + + template<size_t N> + size_t find_first(std::bitset<N> const& rSet) + { + for (size_t i = 0; i < N; ++i) + { + if (rSet.test(i)) + return i; + } + assert(false); // see current usage + return N; + } + + UScriptCode getScript(const vcl::FontCapabilities &rFontCapabilities) + { + using vcl::UnicodeCoverage::UnicodeCoverageEnum; + + std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> aMasked; + if (rFontCapabilities.oUnicodeRange) + { + aMasked = *rFontCapabilities.oUnicodeRange & getWeakMask(); + } + + if (aMasked.count() == 1) + return otCoverageToScript(static_cast<UnicodeCoverageEnum>(find_first(aMasked))); + + if (aMasked[vcl::UnicodeCoverage::ARABIC]) + { + aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A, false); + aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B, false); + aMasked.set(vcl::UnicodeCoverage::NKO, false); + //Probably strongly tuned for Arabic + if (aMasked.count() == 1) + return USCRIPT_ARABIC; + if (aMasked.count() == 2 && aMasked[vcl::UnicodeCoverage::SYRIAC]) + return USCRIPT_SYRIAC; + } + + if (aMasked[vcl::UnicodeCoverage::DEVANAGARI]) + { + aMasked.set(vcl::UnicodeCoverage::DEVANAGARI, false); + //Probably strongly tuned for a single Indic script + if (aMasked.count() == 1) + return otCoverageToScript(static_cast<UnicodeCoverageEnum>(find_first(aMasked))); + } + + aMasked.set(vcl::UnicodeCoverage::GREEK_EXTENDED, false); + aMasked.set(vcl::UnicodeCoverage::GREEK_AND_COPTIC, false); + if (aMasked.count() == 1) + return otCoverageToScript(static_cast<UnicodeCoverageEnum>(find_first(aMasked))); + + if (aMasked[vcl::UnicodeCoverage::CYRILLIC]) + { + //Probably strongly tuned for Georgian + if (aMasked.count() == 2 && aMasked[vcl::UnicodeCoverage::GEORGIAN]) + return USCRIPT_GEORGIAN; + } + + aMasked &= getCJKMask(); + + aMasked.set(vcl::UnicodeCoverage::CYRILLIC, false); + aMasked.set(vcl::UnicodeCoverage::THAI, false); + aMasked.set(vcl::UnicodeCoverage::DESERET, false); + aMasked.set(vcl::UnicodeCoverage::PHAGS_PA, false); + + //So, possibly a CJK font + if (!aMasked.count() && rFontCapabilities.oCodePageRange) + { + std::bitset<vcl::CodePageCoverage::MAX_CP_ENUM> aCJKCodePageMask; + aCJKCodePageMask.set(vcl::CodePageCoverage::CP932); + aCJKCodePageMask.set(vcl::CodePageCoverage::CP936); + aCJKCodePageMask.set(vcl::CodePageCoverage::CP949); + aCJKCodePageMask.set(vcl::CodePageCoverage::CP950); + aCJKCodePageMask.set(vcl::CodePageCoverage::CP1361); + std::bitset<vcl::CodePageCoverage::MAX_CP_ENUM> aMaskedCodePage = + *rFontCapabilities.oCodePageRange & aCJKCodePageMask; + //fold Korean + if (aMaskedCodePage[vcl::CodePageCoverage::CP1361]) + { + aMaskedCodePage.set(vcl::CodePageCoverage::CP949); + aMaskedCodePage.set(vcl::CodePageCoverage::CP1361, false); + } + + if (aMaskedCodePage.count() == 1) + { + if (aMaskedCodePage[vcl::CodePageCoverage::CP932]) + return USCRIPT_JAPANESE; + if (aMaskedCodePage[vcl::CodePageCoverage::CP949]) + return USCRIPT_KOREAN; + if (aMaskedCodePage[vcl::CodePageCoverage::CP936]) + return USCRIPT_SIMPLIFIED_HAN; + if (aMaskedCodePage[vcl::CodePageCoverage::CP950]) + return USCRIPT_TRADITIONAL_HAN; + } + + if (aMaskedCodePage.count()) + return USCRIPT_HAN; + } + + return USCRIPT_COMMON; + } +} + +namespace +{ + UScriptCode attemptToDisambiguateHan(UScriptCode eScript, OutputDevice const &rDevice) + { + //If we're a CJK font, see if we seem to be tuned for C, J or K + if (eScript == USCRIPT_HAN) + { + const vcl::Font &rFont = rDevice.GetFont(); + + bool bKore = false, bJpan = false, bHant = false, bHans = false; + + static const sal_Unicode aKorean[] = { 0x3131 }; + OUString sKorean(aKorean, SAL_N_ELEMENTS(aKorean)); + if (-1 == rDevice.HasGlyphs(rFont, sKorean)) + bKore = true; + + static const sal_Unicode aJapanese[] = { 0x3007, 0x9F9D }; + OUString sJapanese(aJapanese, SAL_N_ELEMENTS(aJapanese)); + if (-1 == rDevice.HasGlyphs(rFont, sJapanese)) + bJpan = true; + + static const sal_Unicode aTraditionalChinese[] = { 0x570B }; + OUString sTraditionalChinese(aTraditionalChinese, SAL_N_ELEMENTS(aTraditionalChinese)); + if (-1 == rDevice.HasGlyphs(rFont, sTraditionalChinese)) + bHant = true; + + static const sal_Unicode aSimplifiedChinese[] = { 0x56FD }; + OUString sSimplifiedChinese(aSimplifiedChinese, SAL_N_ELEMENTS(aSimplifiedChinese)); + if (-1 == rDevice.HasGlyphs(rFont, sSimplifiedChinese)) + bHans = true; + + if (bKore && !bJpan && !bHans) + eScript = USCRIPT_KOREAN; + else if (bJpan && !bKore && !bHans) + 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 combined Hant/Hans preview + } + return eScript; + } +} + +OUString makeShortRepresentativeTextForSelectedFont(OutputDevice const &rDevice) +{ + UScriptCode eScript = lcl_getHardCodedScriptNameForFont(rDevice); + if (eScript == USCRIPT_INVALID_CODE) + { + vcl::FontCapabilities aFontCapabilities; + if (!rDevice.GetFontCapabilities(aFontCapabilities)) + return OUString(); + +#if OSL_DEBUG_LEVEL > 0 + lcl_dump_unicode_coverage(aFontCapabilities.oUnicodeRange); + lcl_dump_codepage_coverage(aFontCapabilities.oCodePageRange); +#endif + + if (aFontCapabilities.oUnicodeRange) + *aFontCapabilities.oUnicodeRange &= getCommonLatnSubsetMask(); + + //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 + eScript = getScript(aFontCapabilities); + if (eScript == USCRIPT_COMMON) + return OUString(); + + eScript = attemptToDisambiguateHan(eScript, rDevice); + } + + OUString sSampleText = makeShortRepresentativeTextForScript(eScript); + bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText)); + return bHasSampleTextGlyphs ? sSampleText : OUString(); +} + +UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCoverageEnum eOTCoverage) +{ + UScriptCode eRet = USCRIPT_COMMON; + switch (eOTCoverage) + { + case vcl::UnicodeCoverage::BASIC_LATIN: + case vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT: + case vcl::UnicodeCoverage::LATIN_EXTENDED_A: + case vcl::UnicodeCoverage::LATIN_EXTENDED_B: + eRet = USCRIPT_LATIN; + break; + case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS: + eRet = USCRIPT_INHERITED; + break; + case vcl::UnicodeCoverage::GREEK_AND_COPTIC: + eRet = USCRIPT_GREEK; + break; + case vcl::UnicodeCoverage::COPTIC: + eRet = USCRIPT_COPTIC; + break; + case vcl::UnicodeCoverage::CYRILLIC: + eRet = USCRIPT_CYRILLIC; + break; + case vcl::UnicodeCoverage::ARMENIAN: + eRet = USCRIPT_ARMENIAN; + break; + case vcl::UnicodeCoverage::HEBREW: + eRet = USCRIPT_HEBREW; + break; + case vcl::UnicodeCoverage::VAI: + eRet = USCRIPT_VAI; + break; + case vcl::UnicodeCoverage::ARABIC: + eRet = USCRIPT_ARABIC; + break; + case vcl::UnicodeCoverage::NKO: + eRet = USCRIPT_NKO; + break; + case vcl::UnicodeCoverage::DEVANAGARI: + eRet = USCRIPT_DEVANAGARI; + break; + case vcl::UnicodeCoverage::BENGALI: + eRet = USCRIPT_BENGALI; + break; + case vcl::UnicodeCoverage::GURMUKHI: + eRet = USCRIPT_GURMUKHI; + break; + case vcl::UnicodeCoverage::GUJARATI: + eRet = USCRIPT_GUJARATI; + break; + case vcl::UnicodeCoverage::ODIA: + eRet = USCRIPT_ORIYA; + break; + case vcl::UnicodeCoverage::TAMIL: + eRet = USCRIPT_TAMIL; + break; + case vcl::UnicodeCoverage::TELUGU: + eRet = USCRIPT_TELUGU; + break; + case vcl::UnicodeCoverage::KANNADA: + eRet = USCRIPT_KANNADA; + break; + case vcl::UnicodeCoverage::MALAYALAM: + eRet = USCRIPT_MALAYALAM; + break; + case vcl::UnicodeCoverage::THAI: + eRet = USCRIPT_THAI; + break; + case vcl::UnicodeCoverage::LAO: + eRet = USCRIPT_LAO; + break; + case vcl::UnicodeCoverage::GEORGIAN: + eRet = USCRIPT_GEORGIAN; + break; + case vcl::UnicodeCoverage::BALINESE: + eRet = USCRIPT_BALINESE; + break; + case vcl::UnicodeCoverage::HANGUL_JAMO: + eRet = USCRIPT_HANGUL; + break; + case vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL: + eRet = USCRIPT_LATIN; + break; + case vcl::UnicodeCoverage::GREEK_EXTENDED: + eRet = USCRIPT_GREEK; + break; + case vcl::UnicodeCoverage::CURRENCY_SYMBOLS: + eRet = USCRIPT_SYMBOLS; + break; + case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS: + eRet = USCRIPT_INHERITED; + break; + case vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS: + case vcl::UnicodeCoverage::NUMBER_FORMS: + case vcl::UnicodeCoverage::ARROWS: + eRet = USCRIPT_SYMBOLS; + break; + case vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS: + eRet = USCRIPT_MATHEMATICAL_NOTATION; + break; + case vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL: + case vcl::UnicodeCoverage::OPTICAL_CHARACTER_RECOGNITION: + case vcl::UnicodeCoverage::BOX_DRAWING: + case vcl::UnicodeCoverage::BLOCK_ELEMENTS: + case vcl::UnicodeCoverage::GEOMETRIC_SHAPES: + case vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS: + case vcl::UnicodeCoverage::DINGBATS: + case vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION: + eRet = USCRIPT_SYMBOLS; + break; + case vcl::UnicodeCoverage::HIRAGANA: + eRet = USCRIPT_HIRAGANA; + break; + case vcl::UnicodeCoverage::KATAKANA: + eRet = USCRIPT_KATAKANA; + break; + case vcl::UnicodeCoverage::BOPOMOFO: + eRet = USCRIPT_BOPOMOFO; + break; + case vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO: + eRet = USCRIPT_HANGUL; + break; + case vcl::UnicodeCoverage::PHAGS_PA: + eRet = USCRIPT_PHAGS_PA; + break; + case vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS: + eRet = USCRIPT_HANGUL; + break; + case vcl::UnicodeCoverage::CJK_COMPATIBILITY: + eRet = USCRIPT_HAN; + break; + case vcl::UnicodeCoverage::HANGUL_SYLLABLES: + eRet = USCRIPT_HANGUL; + break; + case vcl::UnicodeCoverage::PHOENICIAN: + eRet = USCRIPT_PHOENICIAN; + break; + case vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS: + case vcl::UnicodeCoverage::CJK_STROKES: + eRet = USCRIPT_HAN; + break; + case vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A: + eRet = USCRIPT_ARABIC; + break; + case vcl::UnicodeCoverage::COMBINING_HALF_MARKS: + eRet = USCRIPT_INHERITED; + break; + case vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B: + eRet = USCRIPT_ARABIC; + break; + case vcl::UnicodeCoverage::TIBETAN: + eRet = USCRIPT_TIBETAN; + break; + case vcl::UnicodeCoverage::SYRIAC: + eRet = USCRIPT_SYRIAC; + break; + case vcl::UnicodeCoverage::THAANA: + eRet = USCRIPT_THAANA; + break; + case vcl::UnicodeCoverage::SINHALA: + eRet = USCRIPT_SINHALA; + break; + case vcl::UnicodeCoverage::MYANMAR: + eRet = USCRIPT_MYANMAR; + break; + case vcl::UnicodeCoverage::ETHIOPIC: + eRet = USCRIPT_ETHIOPIC; + break; + case vcl::UnicodeCoverage::CHEROKEE: + eRet = USCRIPT_CHEROKEE; + break; + case vcl::UnicodeCoverage::UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS: + eRet = USCRIPT_CANADIAN_ABORIGINAL; + break; + case vcl::UnicodeCoverage::OGHAM: + eRet = USCRIPT_OGHAM; + break; + case vcl::UnicodeCoverage::RUNIC: + eRet = USCRIPT_RUNIC; + break; + case vcl::UnicodeCoverage::KHMER: + eRet = USCRIPT_KHMER; + break; + case vcl::UnicodeCoverage::MONGOLIAN: + eRet = USCRIPT_MONGOLIAN; + break; + case vcl::UnicodeCoverage::BRAILLE_PATTERNS: + eRet = USCRIPT_BRAILLE; + break; + case vcl::UnicodeCoverage::YI_SYLLABLES: + eRet = USCRIPT_YI; + break; + case vcl::UnicodeCoverage::TAGALOG: + eRet = USCRIPT_TAGALOG; + break; + case vcl::UnicodeCoverage::OLD_ITALIC: + eRet = USCRIPT_OLD_ITALIC; + break; + case vcl::UnicodeCoverage::GOTHIC: + eRet = USCRIPT_GOTHIC; + break; + case vcl::UnicodeCoverage::DESERET: + eRet = USCRIPT_DESERET; + break; + case vcl::UnicodeCoverage::BYZANTINE_MUSICAL_SYMBOLS: + case vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS: + case vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15: + eRet = USCRIPT_SYMBOLS; + break; + case vcl::UnicodeCoverage::VARIATION_SELECTORS: + eRet = USCRIPT_INHERITED; + break; + case vcl::UnicodeCoverage::TAGS: + eRet = USCRIPT_SYMBOLS; + break; + case vcl::UnicodeCoverage::LIMBU: + eRet = USCRIPT_LIMBU; + break; + case vcl::UnicodeCoverage::TAI_LE: + eRet = USCRIPT_TAI_LE; + break; + case vcl::UnicodeCoverage::NEW_TAI_LUE: + eRet = USCRIPT_NEW_TAI_LUE; + break; + case vcl::UnicodeCoverage::BUGINESE: + eRet = USCRIPT_BUGINESE; + break; + case vcl::UnicodeCoverage::GLAGOLITIC: + eRet = USCRIPT_GLAGOLITIC; + break; + case vcl::UnicodeCoverage::TIFINAGH: + eRet = USCRIPT_TIFINAGH; + break; + case vcl::UnicodeCoverage::YIJING_HEXAGRAM_SYMBOLS: + eRet = USCRIPT_SYMBOLS; + break; + case vcl::UnicodeCoverage::SYLOTI_NAGRI: + eRet = USCRIPT_SYLOTI_NAGRI; + break; + case vcl::UnicodeCoverage::LINEAR_B_SYLLABARY: + eRet = USCRIPT_LINEAR_B; + break; + case vcl::UnicodeCoverage::ANCIENT_GREEK_NUMBERS: + eRet = USCRIPT_GREEK; + break; + case vcl::UnicodeCoverage::UGARITIC: + eRet = USCRIPT_UGARITIC; + break; + case vcl::UnicodeCoverage::OLD_PERSIAN: + eRet = USCRIPT_OLD_PERSIAN; + break; + case vcl::UnicodeCoverage::SHAVIAN: + eRet = USCRIPT_SHAVIAN; + break; + case vcl::UnicodeCoverage::OSMANYA: + eRet = USCRIPT_OSMANYA; + break; + case vcl::UnicodeCoverage::CYPRIOT_SYLLABARY: + eRet = USCRIPT_CYPRIOT; + break; + case vcl::UnicodeCoverage::KHAROSHTHI: + eRet = USCRIPT_KHAROSHTHI; + break; + case vcl::UnicodeCoverage::CUNEIFORM: + eRet = USCRIPT_CUNEIFORM; + break; + case vcl::UnicodeCoverage::SUNDANESE: + eRet = USCRIPT_SUNDANESE; + break; + case vcl::UnicodeCoverage::LEPCHA: + eRet = USCRIPT_LEPCHA; + break; + case vcl::UnicodeCoverage::OL_CHIKI: + eRet = USCRIPT_OL_CHIKI; + break; + case vcl::UnicodeCoverage::SAURASHTRA: + eRet = USCRIPT_SAURASHTRA; + break; + case vcl::UnicodeCoverage::KAYAH_LI: + eRet = USCRIPT_KAYAH_LI; + break; + case vcl::UnicodeCoverage::REJANG: + eRet = USCRIPT_REJANG; + break; + case vcl::UnicodeCoverage::CHAM: + eRet = USCRIPT_CHAM; + break; + case vcl::UnicodeCoverage::CARIAN: + eRet = USCRIPT_CARIAN; + break; + case vcl::UnicodeCoverage::DOMINO_TILES: + case vcl::UnicodeCoverage::TAI_XUAN_JING_SYMBOLS: + case vcl::UnicodeCoverage::COUNTING_ROD_NUMERALS: + case vcl::UnicodeCoverage::ANCIENT_SYMBOLS: + 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: + case vcl::UnicodeCoverage::SMALL_FORM_VARIANTS: + case vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS: + case vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0: + case vcl::UnicodeCoverage::NONPLANE_0: + case vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS: + case vcl::UnicodeCoverage::CONTROL_PICTURES: + case vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS: + case vcl::UnicodeCoverage::GENERAL_PUNCTUATION: + case vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS: + case vcl::UnicodeCoverage::RESERVED1: + case vcl::UnicodeCoverage::RESERVED2: + case vcl::UnicodeCoverage::RESERVED3: + case vcl::UnicodeCoverage::RESERVED4: + case vcl::UnicodeCoverage::RESERVED5: + case vcl::UnicodeCoverage::MAX_UC_ENUM: + break; + } + return eRet; +} + +OUString makeRepresentativeTextForFont(sal_Int16 nScriptType, const vcl::Font &rFont) +{ + OUString sRet(makeRepresentativeTextForLanguage(rFont.GetLanguage())); + + ScopedVclPtrInstance< VirtualDevice > aDevice; + if (sRet.isEmpty() || (-1 != aDevice->HasGlyphs(rFont, sRet))) + { + aDevice->SetFont(rFont); + vcl::FontCapabilities aFontCapabilities; + if (aDevice->GetFontCapabilities(aFontCapabilities)) + { +#if OSL_DEBUG_LEVEL > 0 + lcl_dump_unicode_coverage(aFontCapabilities.oUnicodeRange); +#endif + + if (aFontCapabilities.oUnicodeRange) + { + *aFontCapabilities.oUnicodeRange &= getWeakMask(); + + if (nScriptType != css::i18n::ScriptType::ASIAN) + { + *aFontCapabilities.oUnicodeRange &= getCJKMask(); + aFontCapabilities.oCodePageRange.reset(); + } + if (nScriptType != css::i18n::ScriptType::LATIN) + *aFontCapabilities.oUnicodeRange &= getLatinMask(); + if (nScriptType != css::i18n::ScriptType::COMPLEX) + *aFontCapabilities.oUnicodeRange &= getCTLMask(); + } + +#if OSL_DEBUG_LEVEL > 0 + SAL_INFO("svtools", "minimal"); + lcl_dump_unicode_coverage(aFontCapabilities.oUnicodeRange); + lcl_dump_codepage_coverage(aFontCapabilities.oCodePageRange); +#endif + + UScriptCode eScript = getScript(aFontCapabilities); + + if (nScriptType == css::i18n::ScriptType::ASIAN) + eScript = attemptToDisambiguateHan(eScript, *aDevice); + + sRet = makeRepresentativeTextForScript(eScript); + } + + if (sRet.isEmpty()) + { + if (nScriptType == css::i18n::ScriptType::COMPLEX) + { + sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW); + if (-1 != aDevice->HasGlyphs(rFont, sRet)) + { + sRet = makeMinimalTextForScript(USCRIPT_HEBREW); + if (-1 != aDevice->HasGlyphs(rFont, sRet)) + sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC); + } + } + else if (nScriptType == css::i18n::ScriptType::LATIN) + sRet = makeRepresentativeTextForScript(USCRIPT_LATIN); + } + } + + return sRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |