/* -*- 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>
#include <vector>
#include <map>
 
// 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") ||
            IsOpenSymbol(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 constexpr OUString aImplAppleSymbolText =
            u"\u03BC\u2202\u2211\u220F\u03C0\u222B\u03A9\u221A"_ustr;
        bool bHasSampleTextGlyphs
            = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), aImplAppleSymbolText));
        //It's the Apple version
        if (bHasSampleTextGlyphs)
            return aImplAppleSymbolText;
        static constexpr OUStringLiteral aImplAdobeSymbolText =
            u"\uF06D\uF0B6\uF0E5\uF0D5\uF070\uF0F2\uF057\uF0D6";
        return aImplAdobeSymbolText;
    }
 
    const bool bOpenSymbol = IsOpenSymbol(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 constexpr OUStringLiteral aGrek =
                u"\u0391\u03BB\u03C6\u03AC\u03B2\u03B7\u03C4\u03BF";
            sSampleText = aGrek;
            break;
        }
        case USCRIPT_HEBREW:
        {
            static constexpr OUStringLiteral aHebr =
                u"\u05D0\u05DC\u05E3\u05BE\u05D1\u05D9\u05EA "
                "\u05E2\u05D1\u05E8\u05D9";
            sSampleText = aHebr;
            break;
        }
        case USCRIPT_ARABIC:
        {
            static constexpr OUStringLiteral aArab =
                u"\u0623\u0628\u062C\u062F\u064A\u0629 \u0639"
                "\u0631\u0628\u064A\u0629";
            sSampleText = aArab;
            break;
        }
        case USCRIPT_ARMENIAN:
        {
            static constexpr OUStringLiteral aArmenian =
                u"\u0561\u0575\u0562\u0578\u0582\u0562\u0565"
                "\u0576";
            sSampleText = aArmenian;
            break;
        }
        case USCRIPT_DEVANAGARI:
        {
            static constexpr OUStringLiteral aDeva =
                u"\u0926\u0947\u0935\u0928\u093E\u0917\u0930\u0940";
            sSampleText = aDeva;
            break;
        }
        case USCRIPT_BENGALI:
        {
            static constexpr OUStringLiteral aBeng =
                u"\u09AC\u09BE\u0982\u09B2\u09BE \u09B2\u09BF"
                "\u09AA\u09BF";
            sSampleText = aBeng;
            break;
        }
        case USCRIPT_GURMUKHI:
        {
            static constexpr OUStringLiteral aGuru =
                u"\u0A17\u0A41\u0A30\u0A2E\u0A41\u0A16\u0A40";
            sSampleText = aGuru;
            break;
        }
        case USCRIPT_GUJARATI:
        {
            static constexpr OUStringLiteral aGujr =
                u"\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0aC0 "
                "\u0AB2\u0ABF\u0AAA\u0ABF";
            sSampleText = aGujr;
            break;
        }
        case USCRIPT_ORIYA:
        {
            static constexpr OUStringLiteral aOrya =
                u"\u0B09\u0B24\u0B4D\u0B15\u0B33 \u0B32\u0B3F"
                "\u0B2A\u0B3F";
            sSampleText = aOrya;
            break;
        }
        case USCRIPT_TAMIL:
        {
            static constexpr OUStringLiteral aTaml =
                u"\u0B85\u0BB0\u0BBF\u0B9A\u0BCD\u0B9A\u0BC1\u0BB5"
                "\u0B9F\u0BBF";
            sSampleText = aTaml;
            break;
        }
        case USCRIPT_TELUGU:
        {
            static constexpr OUStringLiteral aTelu =
                u"\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41";
            sSampleText = aTelu;
            break;
        }
        case USCRIPT_KANNADA:
        {
            static constexpr OUStringLiteral aKnda =
                u"\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 \u0CB2\u0CBF"
                "\u0CAA\u0CBF";
            sSampleText = aKnda;
            break;
        }
        case USCRIPT_MALAYALAM:
        {
            static constexpr OUStringLiteral aMlym =
                u"\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D32\u0D3F\u0D2A"
                "\u0D3F";
            sSampleText = aMlym;
            break;
        }
        case USCRIPT_THAI:
        {
            static constexpr OUStringLiteral aThai =
                u"\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E44\u0E17\u0E22";
            sSampleText = aThai;
            break;
        }
        case USCRIPT_LAO:
        {
            static constexpr OUStringLiteral aLao =
                u"\u0EAD\u0EB1\u0E81\u0EAA\u0EAD\u0E99\u0EA5\u0EB2"
                "\u0EA7";
            sSampleText = aLao;
            break;
        }
        case USCRIPT_GEORGIAN:
        {
            static constexpr OUStringLiteral aGeorgian =
                u"\u10D3\u10D0\u10DB\u10EC\u10D4\u10E0\u10DA\u10DD"
                "\u10D1\u10D0";
            sSampleText = aGeorgian;
            break;
        }
        case USCRIPT_JAMO:
        case USCRIPT_HANGUL:
        case USCRIPT_KOREAN:
        {
            static constexpr OUStringLiteral aHang =
                u"\uD55C\uAE00";
            sSampleText = aHang;
            break;
        }
        case USCRIPT_TIBETAN:
        {
            static constexpr OUStringLiteral aTibt =
                u"\u0F51\u0F56\u0F74\u0F0B\u0F45\u0F53\u0F0B";
            sSampleText = aTibt;
            break;
        }
        case USCRIPT_SYRIAC:
        {
            static constexpr OUStringLiteral aSyri =
                u"\u0723\u071B\u072A\u0722\u0713\u0720\u0710";
            sSampleText = aSyri;
            break;
        }
        case USCRIPT_THAANA:
        {
            static constexpr OUStringLiteral aThaa =
                u"\u078C\u07A7\u0782\u07A6";
            sSampleText = aThaa;
            break;
        }
        case USCRIPT_SINHALA:
        {
            static constexpr OUStringLiteral aSinh =
                u"\u0DC1\u0DD4\u0DAF\u0DCA\u0DB0 \u0DC3\u0DD2"
                "\u0D82\u0DC4\u0DBD";
            sSampleText = aSinh;
            break;
        }
        case USCRIPT_MYANMAR:
        {
            static constexpr OUStringLiteral aMymr =
                u"\u1019\u103C\u1014\u103A\u1019\u102C\u1021\u1000"
                "\u1039\u1001\u101B\u102C";
            sSampleText = aMymr;
            break;
        }
        case USCRIPT_ETHIOPIC:
        {
            static constexpr OUStringLiteral aEthi =
                u"\u130D\u12D5\u12DD";
            sSampleText = aEthi;
            break;
        }
        case USCRIPT_CHEROKEE:
        {
            static constexpr OUStringLiteral aCher =
                u"\u13D7\u13AA\u13EA\u13B6\u13D9\u13D7";
            sSampleText = aCher;
            break;
        }
        case USCRIPT_KHMER:
        {
            static constexpr OUStringLiteral aKhmr =
                u"\u17A2\u1780\u17D2\u1781\u179A\u1780\u17D2\u179A"
                "\u1798\u1781\u17C1\u1798\u179A\u1797\u17B6\u179F"
                "\u17B6";
            sSampleText = aKhmr;
            break;
        }
        case USCRIPT_MONGOLIAN:
        {
            static constexpr OUStringLiteral aMongolian =
                u"\u182A\u1822\u1834\u1822\u182D\u180C";
            sSampleText = aMongolian;
            break;
        }
        case USCRIPT_TAGALOG:
        {
            static constexpr OUStringLiteral aTagalog =
                u"\u170A\u170A\u170C\u1712";
            sSampleText = aTagalog;
            break;
        }
        case USCRIPT_NEW_TAI_LUE:
        {
            static constexpr OUStringLiteral aTalu =
                u"\u1991\u19BA\u199F\u19B9\u19C9";
            sSampleText = aTalu;
            break;
        }
        case USCRIPT_TRADITIONAL_HAN:
        {
            static constexpr OUStringLiteral aHant =
                u"\u7E41";
            sSampleText = aHant;
            break;
        }
        case USCRIPT_SIMPLIFIED_HAN:
        {
            static constexpr OUStringLiteral aHans =
                u"\u7B80";
            sSampleText = aHans;
            break;
        }
        case USCRIPT_HAN:
        {
            static constexpr OUStringLiteral aSimplifiedAndTraditionalChinese =
                u"\u7B80\u7E41";
            sSampleText = aSimplifiedAndTraditionalChinese;
            break;
        }
        case USCRIPT_JAPANESE:
        {
            static constexpr OUStringLiteral aJpan =
                u"\u65E5\u672C\u8A9E";
            sSampleText = aJpan;
            break;
        }
        case USCRIPT_YI:
        {
            static constexpr OUStringLiteral aYiii =
                u"\uA188\uA320\uA071\uA0B7";
            sSampleText = aYiii;
            break;
        }
        case USCRIPT_PHAGS_PA:
        {
            static constexpr OUStringLiteral aPhag =
                u"\uA84F\uA861\uA843 \uA863\uA861\uA859 "
                u"\uA850\uA85C\uA85E";
            sSampleText = aPhag;
            break;
        }
        case USCRIPT_TAI_LE:
        {
            static constexpr OUStringLiteral aTale =
                u"\u1956\u196D\u1970\u1956\u196C\u1973\u1951\u1968"
                "\u1952\u1970";
            sSampleText = 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 constexpr OUStringLiteral aZh =
                u"\u4EBA\u4E4B\u521D \u6027\u672C\u5584";
            sSampleText = aZh;
            break;
        }
        case USCRIPT_JAPANESE:
        {
            //'Beautiful Japanese'
            static constexpr OUStringLiteral aJa =
                u"\u7F8E\u3057\u3044\u65E5\u672C\u8A9E";
            sSampleText = aJa;
            break;
        }
        case USCRIPT_JAMO:
        case USCRIPT_KOREAN:
        case USCRIPT_HANGUL:
        {
            //The essential condition for...
            static constexpr OUStringLiteral aKo =
                u"\uD0A4\uC2A4\uC758 \uACE0\uC720\uC870"
                "\uAC74\uC740";
            sSampleText = aKo;
            break;
        }
        default:
            break;
    }
 
    if (sSampleText.isEmpty())
        sSampleText = makeShortRepresentativeTextForScript(eScript);
    return sSampleText;
}
 
OUString makeShortMinimalTextForScript(UScriptCode eScript)
{
    OUString sSampleText;
    switch (eScript)
    {
        case USCRIPT_GREEK:
        {
            static constexpr OUStringLiteral aGrek =
                u"\u0391\u0392";
            sSampleText = aGrek;
            break;
        }
        case USCRIPT_HEBREW:
        {
            static constexpr OUStringLiteral aHebr =
                u"\u05D0\u05D1";
            sSampleText = 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 it's 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 constexpr OUStringLiteral aAs =
            u"\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE"
            " \u0986\u0996\u09F0";
        sRet = 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 constexpr OUStringLiteral aGa =
            u"T\u00E9acs Samplach";
        sRet = 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]))
            return;
 
        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]))
            return;
 
        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);
        // tdf#88484
        // Some fonts set the Arabic Presentation Forms-B bit because they
        // support U+FEFF (Zero Width Space) which happens to be in that block
        // but it isn’t an Arabic code point. By the time we reach here we
        // decided this isn’t an Arabic font, so it should be safe.
        aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B, 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;
    }
}
 
const std::map<UScriptCode, std::vector<OUString>> distCjkMap =
{
    { USCRIPT_KOREAN,  { u" KR"_ustr, u"Korean"_ustr} },   // Korean
    { USCRIPT_JAPANESE, {u" JP"_ustr, u"Japanese"_ustr} } , // Japanese
    { USCRIPT_SIMPLIFIED_HAN, {u" SC"_ustr, u" GB"_ustr, u"S Chinese"_ustr} }, // Simplified Chinese Family
    { USCRIPT_TRADITIONAL_HAN, {u" TC"_ustr, u" HC"_ustr, u" TW"_ustr, u" HK"_ustr, u" MO"_ustr, u"T Chinese"_ustr} }// Traditional Chinese Family
};
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 constexpr OUStringLiteral sKorean = u"\u4E6D\u4E76\u596C";
            if (-1 == rDevice.HasGlyphs(rFont, sKorean))
                bKore = true;
 
            static constexpr OUStringLiteral sJapanese = u"\u5968\u67A0\u9D8F";
            if (-1 == rDevice.HasGlyphs(rFont, sJapanese))
                bJpan = true;
 
            static constexpr OUStringLiteral sTraditionalChinese = u"\u555F\u96DE";
            if (-1 == rDevice.HasGlyphs(rFont, sTraditionalChinese))
                bHant = true;
 
            static constexpr OUStringLiteral sSimplifiedChinese = u"\u4E61\u542F\u5956";
            if (-1 == rDevice.HasGlyphs(rFont, sSimplifiedChinese))
                bHans = true;
 
            if (bKore && !bJpan && !bHans && !bHant) {
                eScript = USCRIPT_KOREAN;
                return eScript;
            }
            else if (bJpan && !bKore && !bHans && !bHant) {
                eScript = USCRIPT_JAPANESE;
                return eScript;
            }
            else if (bHans && !bHant && !bKore && !bJpan) {
                eScript = USCRIPT_SIMPLIFIED_HAN;
                return eScript;
            }
            else if (bHant && !bHans && !bKore && !bJpan) {
                eScript = USCRIPT_TRADITIONAL_HAN;
                return eScript;
            }
 
            // for the last time, Check the ISO code strings or font specific strings
            const OUString &rName = rDevice.GetFont().GetFamilyName();
            std::map<UScriptCode, std::vector<OUString>>::const_iterator distCjkMapIt;
            for (distCjkMapIt = distCjkMap.begin(); distCjkMapIt != distCjkMap.end(); ++distCjkMapIt) {
                std::vector<OUString> cjkCodeList = distCjkMapIt->second;
                std::vector<OUString>::const_iterator cjkPtr;
                for (cjkPtr = cjkCodeList.begin(); cjkPtr != cjkCodeList.end(); ++cjkPtr) {
                    if (rName.indexOf(*cjkPtr) > 0) {
                        return distCjkMapIt->first;
                    }
                }
            }
            //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: */

V1037 Two or more case-branches perform the same actions. Check lines: 1295, 1367

V1037 Two or more case-branches perform the same actions. Check lines: 1301, 1370, 1529

V1037 Two or more case-branches perform the same actions. Check lines: 1319, 1428, 1434

V1037 Two or more case-branches perform the same actions. Check lines: 1415, 1425