nss: upgrade to release 3.73
[LibreOffice.git] / svtools / source / misc / sampletext.cxx
blob1cd48482bc62ff7fc0b00a1c2ab07eaa2de82e56
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9 #include <svtools/sampletext.hxx>
10 #include <vcl/font.hxx>
11 #include <vcl/outdev.hxx>
12 #include <vcl/virdev.hxx>
13 #include <vcl/fontcharmap.hxx>
14 #include <i18nutil/unicode.hxx>
15 #include <sal/log.hxx>
16 #include <com/sun/star/i18n/ScriptType.hpp>
17 #include <vector>
18 #include <map>
20 // This should only be used when a commonly used font incorrectly declares its
21 // coverage. If you add a font here, please leave a note explaining the issue
22 // that caused it to be added
23 static UScriptCode lcl_getHardCodedScriptNameForFont (const OutputDevice &rDevice)
25 const OUString &rName = rDevice.GetFont().GetFamilyName();
27 if (rName == "GB18030 Bitmap")
29 // As of OSX 10.9, the system font "GB18030 Bitmap" incorrectly declares
30 // that it only covers "Phoenician" when in fact it's a Chinese font.
31 return USCRIPT_HAN;
33 else if (rName == "BiauKai")
35 // "BiauKai" makes crazy claims to cover BUGINESE, SUNDANESE, etc
36 // but in fact it's a Traditional Chinese font.
37 return USCRIPT_TRADITIONAL_HAN;
39 else if (rName == "GungSeo" || rName == "PCMyungjo" || rName == "PilGi")
41 // These have no OS/2 tables, but we know they are Korean fonts.
42 return USCRIPT_KOREAN;
44 else if (rName == "Hei" || rName == "Kai")
46 // These have no OS/2 tables, but we know they are Chinese fonts.
47 return USCRIPT_HAN;
49 else if (rName.startsWith("Bangla "))
51 // "Bangla Sangam MN" claims it supports MALAYALAM, but it doesn't
52 // "Bangla MN" claims just DEVANAGARI and not an additional BENGALI
53 return USCRIPT_BENGALI;
55 else if (rName.startsWith("Gurmukhi "))
57 // "Gurmukhi MN" claims it supports TAMIL, but it doesn't
58 return USCRIPT_GURMUKHI;
60 else if (rName.startsWith("Kannada "))
62 // "Kannada MN" claims it supports TAMIL, but it doesn't
63 return USCRIPT_KANNADA;
65 else if (rName.startsWith("Lao "))
67 // "Lao Sangam MN" claims it supports TAMIL, but it doesn't
68 return USCRIPT_LAO;
70 else if (rName.startsWith("Malayalam "))
72 // "Malayalam MN" claims it supports TAMIL, but it doesn't
73 return USCRIPT_MALAYALAM;
75 else if (rName.startsWith("Sinhala "))
77 // "Sinhala MN" claims it supports CYRILLIC
78 return USCRIPT_SINHALA;
80 else if (rName.startsWith("Telugu "))
82 // "Telugu MN" claims it supports TAMIL, but it doesn't
83 return USCRIPT_TELUGU;
85 else if (rName.startsWith("Myanmar "))
87 return USCRIPT_MYANMAR;
89 else if (rName == "InaiMathi")
91 // "InaiMathi" claims it supports GOTHIC and CJK_UNIFIED_IDEOGRAPHS as well as
92 // TAMIL, but it doesn't
93 return USCRIPT_TAMIL;
95 else if (rName == "Hannotate TC" || rName == "HanziPen TC" || rName == "Heiti TC" || rName == "Weibei TC")
97 // These fonts claim support for ARMENIAN and a bunch of other stuff they don't support
98 return USCRIPT_TRADITIONAL_HAN;
100 else if (rName == "Hannotate SC" || rName == "HanziPen SC" || rName == "Heiti SC" || rName == "Weibei SC")
102 // These fonts claim support for ARMENIAN and a bunch of other stuff they don't support
103 return USCRIPT_SIMPLIFIED_HAN;
105 return USCRIPT_INVALID_CODE;
108 bool isSymbolFont(const vcl::Font &rFont)
110 return (rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL) ||
111 rFont.GetFamilyName().equalsIgnoreAsciiCase("Apple Color Emoji") ||
112 rFont.GetFamilyName().equalsIgnoreAsciiCase("cmsy10") ||
113 rFont.GetFamilyName().equalsIgnoreAsciiCase("cmex10") ||
114 rFont.GetFamilyName().equalsIgnoreAsciiCase("esint10") ||
115 rFont.GetFamilyName().equalsIgnoreAsciiCase("feta26") ||
116 rFont.GetFamilyName().equalsIgnoreAsciiCase("jsMath-cmsy10") ||
117 rFont.GetFamilyName().equalsIgnoreAsciiCase("jsMath-cmex10") ||
118 rFont.GetFamilyName().equalsIgnoreAsciiCase("msam10") ||
119 rFont.GetFamilyName().equalsIgnoreAsciiCase("msbm10") ||
120 rFont.GetFamilyName().equalsIgnoreAsciiCase("wasy10") ||
121 rFont.GetFamilyName().equalsIgnoreAsciiCase("Denemo") ||
122 rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic1") ||
123 rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic2") ||
124 rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic3") ||
125 rFont.GetFamilyName().equalsIgnoreAsciiCase("GlyphBasic4") ||
126 rFont.GetFamilyName().equalsIgnoreAsciiCase("Letters Laughing") ||
127 rFont.GetFamilyName().equalsIgnoreAsciiCase("MusiQwik") ||
128 rFont.GetFamilyName().equalsIgnoreAsciiCase("MusiSync") ||
129 rFont.GetFamilyName().equalsIgnoreAsciiCase("stmary10") ||
130 rFont.GetFamilyName().equalsIgnoreAsciiCase("Symbol") ||
131 rFont.GetFamilyName().equalsIgnoreAsciiCase("Webdings") ||
132 rFont.GetFamilyName().equalsIgnoreAsciiCase("Wingdings") ||
133 rFont.GetFamilyName().equalsIgnoreAsciiCase("Wingdings 2") ||
134 rFont.GetFamilyName().equalsIgnoreAsciiCase("Wingdings 3") ||
135 rFont.GetFamilyName().equalsIgnoreAsciiCase("Bookshelf Symbol 7") ||
136 rFont.GetFamilyName().startsWith("STIXIntegrals") ||
137 rFont.GetFamilyName().startsWith("STIXNonUnicode") ||
138 rFont.GetFamilyName().startsWith("STIXSize") ||
139 rFont.GetFamilyName().startsWith("STIXVariants") ||
140 IsStarSymbol(rFont.GetFamilyName());
143 bool canRenderNameOfSelectedFont(OutputDevice const &rDevice)
145 const vcl::Font &rFont = rDevice.GetFont();
146 return !isSymbolFont(rFont) && ( -1 == rDevice.HasGlyphs(rFont, rFont.GetFamilyName()) );
149 OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice const &rDevice)
151 if (rDevice.GetFont().GetFamilyName() == "Symbol")
153 static const sal_Unicode aImplAppleSymbolText[] = {
154 0x03BC, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x03A9, 0x221A, 0};
155 bool bHasSampleTextGlyphs
156 = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), aImplAppleSymbolText));
157 //It's the Apple version
158 if (bHasSampleTextGlyphs)
159 return aImplAppleSymbolText;
160 static const sal_Unicode aImplAdobeSymbolText[] = {
161 0xF06D, 0xF0B6, 0xF0E5, 0xF0D5, 0xF070, 0xF0F2, 0xF057, 0xF0D6, 0};
162 return aImplAdobeSymbolText;
165 const bool bOpenSymbol = IsStarSymbol(rDevice.GetFont().GetFamilyName());
167 if (!bOpenSymbol)
169 FontCharMapRef xFontCharMap;
170 bool bHasCharMap = rDevice.GetFontCharMap(xFontCharMap);
171 if( bHasCharMap )
173 // use some sample characters available in the font
174 sal_Unicode aText[8];
176 // start just above the PUA used by most symbol fonts
177 sal_uInt32 cNewChar = 0xFF00;
179 const int nMaxCount = SAL_N_ELEMENTS(aText) - 1;
180 int nSkip = xFontCharMap->GetCharCount() / nMaxCount;
181 if( nSkip > 10 )
182 nSkip = 10;
183 else if( nSkip <= 0 )
184 nSkip = 1;
185 for( int i = 0; i < nMaxCount; ++i )
187 sal_uInt32 cOldChar = cNewChar;
188 for( int j = nSkip; --j >= 0; )
189 cNewChar = xFontCharMap->GetPrevChar( cNewChar );
190 if( cOldChar == cNewChar )
191 break;
192 aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples
193 aText[ i+1 ] = 0;
196 return OUString(aText);
200 static const sal_Unicode aImplSymbolFontText[] = {
201 0xF021,0xF032,0xF043,0xF054,0xF065,0xF076,0xF0B7,0xF0C8,0};
202 static const sal_Unicode aImplStarSymbolText[] = {
203 0x2702,0x2708,0x270D,0xE033,0x2211,0x2288,0};
204 const sal_Unicode* pText = bOpenSymbol ? aImplStarSymbolText : aImplSymbolFontText;
205 OUString sSampleText(pText);
206 bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText));
207 return bHasSampleTextGlyphs ? sSampleText : OUString();
210 //These ones are typically for use in the font dropdown box beside the
211 //fontname, so say things roughly like "Script/Alphabet/Name-Of-Major-Language"
213 //Here we don't always know the language of course, only the script that can be
214 //written with the font. Often that's one single language written in that
215 //script, or a handful of related languages where the name of the script is the
216 //same between languages, or the name in the major language is known by most
217 //readers of the minor languages, e.g. Yiddish is written with the HEBREW
218 //script as well, the vast majority of Yiddish readers will be able to read
219 //Hebrew as well.
220 OUString makeShortRepresentativeTextForScript(UScriptCode eScript)
222 OUString sSampleText;
223 switch (eScript)
225 case USCRIPT_GREEK:
227 static const sal_Unicode aGrek[] = {
228 0x0391, 0x03BB, 0x03C6, 0x03AC, 0x03B2, 0x03B7, 0x03C4, 0x03BF
230 sSampleText = OUString(aGrek, SAL_N_ELEMENTS(aGrek));
231 break;
233 case USCRIPT_HEBREW:
235 static const sal_Unicode aHebr[] = {
236 0x05D0, 0x05B8, 0x05DC, 0x05B6, 0x05E3, 0x05BE, 0x05D1, 0x05B5,
237 0x05BC, 0x05D9, 0x05EA, 0x0020, 0x05E2, 0x05B4, 0x05D1, 0x05B0,
238 0x05E8, 0x05B4, 0x05D9
240 sSampleText = OUString(aHebr, SAL_N_ELEMENTS(aHebr));
241 break;
243 case USCRIPT_ARABIC:
245 static const sal_Unicode aArab[] = {
246 0x0623, 0x0628, 0x062C, 0x062F, 0x064A, 0x0629, 0x0020, 0x0639,
247 0x0631, 0x0628, 0x064A, 0x0629
249 sSampleText = OUString(aArab, SAL_N_ELEMENTS(aArab));
250 break;
252 case USCRIPT_ARMENIAN:
254 static const sal_Unicode aArmenian[] = {
255 0x0561, 0x0575, 0x0562, 0x0578, 0x0582, 0x0562, 0x0565,
256 0x0576
258 sSampleText = OUString(aArmenian, SAL_N_ELEMENTS(aArmenian));
259 break;
261 case USCRIPT_DEVANAGARI:
263 static const sal_Unicode aDeva[] = {
264 0x0926, 0x0947, 0x0935, 0x0928, 0x093E, 0x0917, 0x0930, 0x0940
266 sSampleText = OUString(aDeva, SAL_N_ELEMENTS(aDeva));
267 break;
269 case USCRIPT_BENGALI:
271 static const sal_Unicode aBeng[] = {
272 0x09AC, 0x09BE, 0x0982, 0x09B2, 0x09BE, 0x0020, 0x09B2, 0x09BF,
273 0x09AA, 0x09BF
275 sSampleText = OUString(aBeng, SAL_N_ELEMENTS(aBeng));
276 break;
278 case USCRIPT_GURMUKHI:
280 static const sal_Unicode aGuru[] = {
281 0x0A17, 0x0A41, 0x0A30, 0x0A2E, 0x0A41, 0x0A16, 0x0A40
283 sSampleText = OUString(aGuru, SAL_N_ELEMENTS(aGuru));
284 break;
286 case USCRIPT_GUJARATI:
288 static const sal_Unicode aGujr[] = {
289 0x0A97, 0x0AC1, 0x0A9C, 0x0AB0, 0x0ABE, 0x0AA4, 0x0aC0, 0x0020,
290 0x0AB2, 0x0ABF, 0x0AAA, 0x0ABF
292 sSampleText = OUString(aGujr, SAL_N_ELEMENTS(aGujr));
293 break;
295 case USCRIPT_ORIYA:
297 static const sal_Unicode aOrya[] = {
298 0x0B09, 0x0B24, 0x0B4D, 0x0B15, 0x0B33, 0x0020, 0x0B32, 0x0B3F,
299 0x0B2A, 0x0B3F
301 sSampleText = OUString(aOrya, SAL_N_ELEMENTS(aOrya));
302 break;
304 case USCRIPT_TAMIL:
306 static const sal_Unicode aTaml[] = {
307 0x0B85, 0x0BB0, 0x0BBF, 0x0B9A, 0x0BCD, 0x0B9A, 0x0BC1, 0x0BB5,
308 0x0B9F, 0x0BBF
310 sSampleText = OUString(aTaml, SAL_N_ELEMENTS(aTaml));
311 break;
313 case USCRIPT_TELUGU:
315 static const sal_Unicode aTelu[] = {
316 0x0C24, 0x0C46, 0x0C32, 0x0C41, 0x0C17, 0x0C41
318 sSampleText = OUString(aTelu, SAL_N_ELEMENTS(aTelu));
319 break;
321 case USCRIPT_KANNADA:
323 static const sal_Unicode aKnda[] = {
324 0x0C95, 0x0CA8, 0x0CCD, 0x0CA8, 0x0CA1, 0x0020, 0x0CB2, 0x0CBF,
325 0x0CAA, 0x0CBF
327 sSampleText = OUString(aKnda, SAL_N_ELEMENTS(aKnda));
328 break;
330 case USCRIPT_MALAYALAM:
332 static const sal_Unicode aMlym[] = {
333 0x0D2E, 0x0D32, 0x0D2F, 0x0D3E, 0x0D33, 0x0D32, 0x0D3F, 0x0D2A,
334 0x0D3F
336 sSampleText = OUString(aMlym, SAL_N_ELEMENTS(aMlym));
337 break;
339 case USCRIPT_THAI:
341 static const sal_Unicode aThai[] = {
342 0x0E2D, 0x0E31, 0x0E01, 0x0E29, 0x0E23, 0x0E44, 0x0E17, 0x0E22
344 sSampleText = OUString(aThai, SAL_N_ELEMENTS(aThai));
345 break;
347 case USCRIPT_LAO:
349 static const sal_Unicode aLao[] = {
350 0x0EAD, 0x0EB1, 0x0E81, 0x0EAA, 0x0EAD, 0x0E99, 0x0EA5, 0x0EB2,
351 0x0EA7
353 sSampleText = OUString(aLao, SAL_N_ELEMENTS(aLao));
354 break;
356 case USCRIPT_GEORGIAN:
358 static const sal_Unicode aGeorgian[] = {
359 0x10D3, 0x10D0, 0x10DB, 0x10EC, 0x10D4, 0x10E0, 0x10DA, 0x10DD,
360 0x10D1, 0x10D0
362 sSampleText = OUString(aGeorgian, SAL_N_ELEMENTS(aGeorgian));
363 break;
365 case USCRIPT_JAMO:
366 case USCRIPT_HANGUL:
367 case USCRIPT_KOREAN:
369 static const sal_Unicode aHang[] = {
370 0xD55C, 0xAE00
372 sSampleText = OUString(aHang, SAL_N_ELEMENTS(aHang));
373 break;
375 case USCRIPT_TIBETAN:
377 static const sal_Unicode aTibt[] = {
378 0x0F51, 0x0F56, 0x0F74, 0x0F0B, 0x0F45, 0x0F53, 0x0F0B
380 sSampleText = OUString(aTibt, SAL_N_ELEMENTS(aTibt));
381 break;
383 case USCRIPT_SYRIAC:
385 static const sal_Unicode aSyri[] = {
386 0x0723, 0x071B, 0x072A, 0x0722, 0x0713, 0x0720, 0x0710
388 sSampleText = OUString(aSyri, SAL_N_ELEMENTS(aSyri));
389 break;
391 case USCRIPT_THAANA:
393 static const sal_Unicode aThaa[] = {
394 0x078C, 0x07A7, 0x0782, 0x07A6
396 sSampleText = OUString(aThaa, SAL_N_ELEMENTS(aThaa));
397 break;
399 case USCRIPT_SINHALA:
401 static const sal_Unicode aSinh[] = {
402 0x0DC1, 0x0DD4, 0x0DAF, 0x0DCA, 0x0DB0, 0x0020, 0x0DC3, 0x0DD2,
403 0x0D82, 0x0DC4, 0x0DBD
405 sSampleText = OUString(aSinh, SAL_N_ELEMENTS(aSinh));
406 break;
408 case USCRIPT_MYANMAR:
410 static const sal_Unicode aMymr[] = {
411 0x1019, 0x103C, 0x1014, 0x103A, 0x1019, 0x102C, 0x1021, 0x1000,
412 0x1039, 0x1001, 0x101B, 0x102C
414 sSampleText = OUString(aMymr, SAL_N_ELEMENTS(aMymr));
415 break;
417 case USCRIPT_ETHIOPIC:
419 static const sal_Unicode aEthi[] = {
420 0x130D, 0x12D5, 0x12DD
422 sSampleText = OUString(aEthi, SAL_N_ELEMENTS(aEthi));
423 break;
425 case USCRIPT_CHEROKEE:
427 static const sal_Unicode aCher[] = {
428 0x13D7, 0x13AA, 0x13EA, 0x13B6, 0x13D9, 0x13D7
430 sSampleText = OUString(aCher, SAL_N_ELEMENTS(aCher));
431 break;
433 case USCRIPT_KHMER:
435 static const sal_Unicode aKhmr[] = {
436 0x17A2, 0x1780, 0x17D2, 0x1781, 0x179A, 0x1780, 0x17D2, 0x179A,
437 0x1798, 0x1781, 0x17C1, 0x1798, 0x179A, 0x1797, 0x17B6, 0x179F,
438 0x17B6
440 sSampleText = OUString(aKhmr, SAL_N_ELEMENTS(aKhmr));
441 break;
443 case USCRIPT_MONGOLIAN:
445 static const sal_Unicode aMongolian[] = {
446 0x182A, 0x1822, 0x1834, 0x1822, 0x182D, 0x180C
448 sSampleText = OUString(aMongolian, SAL_N_ELEMENTS(aMongolian));
449 break;
451 case USCRIPT_TAGALOG:
453 static const sal_Unicode aTagalog[] = {
454 0x170A, 0x170A, 0x170C, 0x1712
456 sSampleText = OUString(aTagalog, SAL_N_ELEMENTS(aTagalog));
457 break;
459 case USCRIPT_NEW_TAI_LUE:
461 static const sal_Unicode aTalu[] = {
462 0x1991, 0x19BA, 0x199F, 0x19B9, 0x19C9
464 sSampleText = OUString(aTalu, SAL_N_ELEMENTS(aTalu));
465 break;
467 case USCRIPT_TRADITIONAL_HAN:
469 static const sal_Unicode aHant[] = {
470 0x7E41
472 sSampleText = OUString(aHant, SAL_N_ELEMENTS(aHant));
473 break;
475 case USCRIPT_SIMPLIFIED_HAN:
477 static const sal_Unicode aHans[] = {
478 0x7B80
480 sSampleText = OUString(aHans, SAL_N_ELEMENTS(aHans));
481 break;
483 case USCRIPT_HAN:
485 static const sal_Unicode aSimplifiedAndTraditionalChinese[] = {
486 0x7B80, 0x7E41
488 sSampleText = OUString(aSimplifiedAndTraditionalChinese,
489 SAL_N_ELEMENTS(aSimplifiedAndTraditionalChinese));
490 break;
492 case USCRIPT_JAPANESE:
494 static const sal_Unicode aJpan[] = {
495 0x65E5, 0x672C, 0x8A9E
497 sSampleText = OUString(aJpan, SAL_N_ELEMENTS(aJpan));
498 break;
500 case USCRIPT_YI:
502 static const sal_Unicode aYiii[] = {
503 0xA188, 0xA320, 0xA071, 0xA0B7
505 sSampleText = OUString(aYiii, SAL_N_ELEMENTS(aYiii));
506 break;
508 case USCRIPT_PHAGS_PA:
510 static const sal_Unicode aPhag[] = {
511 0xA84F, 0xA861, 0xA843, 0x0020, 0xA863, 0xA861, 0xA859, 0x0020,
512 0xA850, 0xA85C, 0xA85E
514 sSampleText = OUString(aPhag, SAL_N_ELEMENTS(aPhag));
515 break;
517 case USCRIPT_TAI_LE:
519 static const sal_Unicode aTale[] = {
520 0x1956, 0x196D, 0x1970, 0x1956, 0x196C, 0x1973, 0x1951, 0x1968,
521 0x1952, 0x1970
523 sSampleText = OUString(aTale, SAL_N_ELEMENTS(aTale));
524 break;
526 case USCRIPT_LATIN:
527 sSampleText = "Lorem ipsum";
528 break;
529 default:
530 break;
532 return sSampleText;
535 static OUString makeRepresentativeTextForScript(UScriptCode eScript)
537 OUString sSampleText;
538 switch (eScript)
540 case USCRIPT_TRADITIONAL_HAN:
541 case USCRIPT_SIMPLIFIED_HAN:
542 case USCRIPT_HAN:
544 //Three Character Classic
545 static const sal_Unicode aZh[] = {
546 0x4EBA, 0x4E4B, 0x521D, 0x0020, 0x6027, 0x672C, 0x5584
548 sSampleText = OUString(aZh, SAL_N_ELEMENTS(aZh));
549 break;
551 case USCRIPT_JAPANESE:
553 //'Beautiful Japanese'
554 static const sal_Unicode aJa[] = {
555 0x7F8E, 0x3057, 0x3044, 0x65E5, 0x672C, 0x8A9E
557 sSampleText = OUString(aJa, SAL_N_ELEMENTS(aJa));
558 break;
560 case USCRIPT_JAMO:
561 case USCRIPT_KOREAN:
562 case USCRIPT_HANGUL:
564 //The essential condition for...
565 static const sal_Unicode aKo[] = {
566 0xD0A4, 0xC2A4, 0xC758, 0x0020, 0xACE0, 0xC720, 0xC870,
567 0xAC74, 0xC740
569 sSampleText = OUString(aKo, SAL_N_ELEMENTS(aKo));
570 break;
572 default:
573 break;
576 if (sSampleText.isEmpty())
577 sSampleText = makeShortRepresentativeTextForScript(eScript);
578 return sSampleText;
581 OUString makeShortMinimalTextForScript(UScriptCode eScript)
583 OUString sSampleText;
584 switch (eScript)
586 case USCRIPT_GREEK:
588 static const sal_Unicode aGrek[] = {
589 0x0391, 0x0392
591 sSampleText = OUString(aGrek, SAL_N_ELEMENTS(aGrek));
592 break;
594 case USCRIPT_HEBREW:
596 static const sal_Unicode aHebr[] = {
597 0x05D0, 0x05D1
599 sSampleText = OUString(aHebr, SAL_N_ELEMENTS(aHebr));
600 break;
602 default:
603 break;
605 return sSampleText;
608 static OUString makeMinimalTextForScript(UScriptCode eScript)
610 return makeShortMinimalTextForScript(eScript);
613 //These ones are typically for use in the font preview window in format
614 //character
616 //There we generally know the language. Though it's possible for the language to
617 //be "none".
619 //Currently we fall back to makeShortRepresentativeTextForScript when we don't
620 //have suitable strings
621 static OUString makeRepresentativeTextForLanguage(LanguageType eLang)
623 OUString sRet;
624 LanguageType pri = primary(eLang);
625 if( pri == primary(LANGUAGE_ARMENIAN) )
626 sRet = makeRepresentativeTextForScript(USCRIPT_ARMENIAN);
627 else if( pri == primary(LANGUAGE_CHINESE) )
628 sRet = makeRepresentativeTextForScript(USCRIPT_HAN);
629 else if( pri == primary(LANGUAGE_GREEK) )
630 sRet = makeRepresentativeTextForScript(USCRIPT_GREEK);
631 else if( pri.anyOf(
632 primary(LANGUAGE_HEBREW),
633 primary(LANGUAGE_YIDDISH)) )
634 sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW);
635 else if( pri == primary(LANGUAGE_ARABIC_SAUDI_ARABIA) )
636 sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC);
637 else if( pri == primary(LANGUAGE_HINDI) )
638 sRet = makeRepresentativeTextForScript(USCRIPT_DEVANAGARI);
639 else if( pri == primary(LANGUAGE_ASSAMESE) )
641 static const sal_Unicode aAs[] = {
642 0x0985, 0x09B8, 0x09AE, 0x09C0, 0x09AF, 0x09BC, 0x09BE,
643 0x0020, 0x0986, 0x0996, 0x09F0
645 sRet = OUString(aAs, SAL_N_ELEMENTS(aAs));
647 else if( pri == primary(LANGUAGE_BENGALI) )
648 sRet = makeRepresentativeTextForScript(USCRIPT_BENGALI);
649 else if( pri == primary(LANGUAGE_PUNJABI) )
650 sRet = makeRepresentativeTextForScript(USCRIPT_GURMUKHI);
651 else if( pri == primary(LANGUAGE_GUJARATI) )
652 sRet = makeRepresentativeTextForScript(USCRIPT_GUJARATI);
653 else if( pri == primary(LANGUAGE_ODIA) )
654 sRet = makeRepresentativeTextForScript(USCRIPT_ORIYA);
655 else if( pri == primary(LANGUAGE_TAMIL) )
656 sRet = makeRepresentativeTextForScript(USCRIPT_TAMIL);
657 else if( pri == primary(LANGUAGE_TELUGU) )
658 sRet = makeRepresentativeTextForScript(USCRIPT_TELUGU);
659 else if( pri == primary(LANGUAGE_KANNADA) )
660 sRet = makeRepresentativeTextForScript(USCRIPT_KANNADA);
661 else if( pri == primary(LANGUAGE_MALAYALAM) )
662 sRet = makeRepresentativeTextForScript(USCRIPT_MALAYALAM);
663 else if( pri == primary(LANGUAGE_THAI) )
664 sRet = makeRepresentativeTextForScript(USCRIPT_THAI);
665 else if( pri == primary(LANGUAGE_LAO) )
666 sRet = makeRepresentativeTextForScript(USCRIPT_LAO);
667 else if( pri == primary(LANGUAGE_GEORGIAN) )
668 sRet = makeRepresentativeTextForScript(USCRIPT_GEORGIAN);
669 else if( pri == primary(LANGUAGE_KOREAN) )
670 sRet = makeRepresentativeTextForScript(USCRIPT_KOREAN);
671 else if( pri == primary(LANGUAGE_TIBETAN) )
672 sRet = makeRepresentativeTextForScript(USCRIPT_TIBETAN);
673 else if( pri == primary(LANGUAGE_SYRIAC) )
674 sRet = makeRepresentativeTextForScript(USCRIPT_SYRIAC);
675 else if( pri == primary(LANGUAGE_SINHALESE_SRI_LANKA) )
676 sRet = makeRepresentativeTextForScript(USCRIPT_SINHALA);
677 else if( pri == primary(LANGUAGE_BURMESE) )
678 sRet = makeRepresentativeTextForScript(USCRIPT_MYANMAR);
679 else if( pri == primary(LANGUAGE_AMHARIC_ETHIOPIA) )
680 sRet = makeRepresentativeTextForScript(USCRIPT_ETHIOPIC);
681 else if( pri == primary(LANGUAGE_CHEROKEE_UNITED_STATES) )
682 sRet = makeRepresentativeTextForScript(USCRIPT_CHEROKEE);
683 else if( pri == primary(LANGUAGE_KHMER) )
684 sRet = makeRepresentativeTextForScript(USCRIPT_KHMER);
685 else if( pri == primary(LANGUAGE_MONGOLIAN_MONGOLIAN_LSO) )
687 if (eLang.anyOf(
688 LANGUAGE_MONGOLIAN_MONGOLIAN_MONGOLIA,
689 LANGUAGE_MONGOLIAN_MONGOLIAN_CHINA,
690 LANGUAGE_MONGOLIAN_MONGOLIAN_LSO))
691 sRet = makeRepresentativeTextForScript(USCRIPT_MONGOLIAN);
693 else if( pri == primary(LANGUAGE_JAPANESE) )
694 sRet = makeRepresentativeTextForScript(USCRIPT_JAPANESE);
695 else if( pri == primary(LANGUAGE_YI) )
696 sRet = makeRepresentativeTextForScript(USCRIPT_YI);
697 else if( pri == primary(LANGUAGE_GAELIC_IRELAND) )
699 static const sal_Unicode aGa[] = {
700 'T', 0x00E9, 'a', 'c', 's', ' ', 'S', 'a', 'm', 'p', 'l', 'a', 'c', 'h'
702 sRet = OUString(aGa, SAL_N_ELEMENTS(aGa));
705 return sRet;
708 namespace
710 #if OSL_DEBUG_LEVEL > 0
711 void lcl_dump_unicode_coverage(const std::optional<std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM>> &roIn)
713 if (!roIn)
715 SAL_INFO("svtools", "<NOTHING>");
716 return;
718 auto & rIn(*roIn);
719 if (rIn.none())
721 SAL_INFO("svtools", "<NONE>");
722 return;
724 if (rIn[vcl::UnicodeCoverage::BASIC_LATIN])
725 SAL_INFO("svtools", "BASIC_LATIN");
726 if (rIn[vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT])
727 SAL_INFO("svtools", "LATIN_1_SUPPLEMENT");
728 if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_A])
729 SAL_INFO("svtools", "LATIN_EXTENDED_A");
730 if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_B])
731 SAL_INFO("svtools", "LATIN_EXTENDED_B");
732 if (rIn[vcl::UnicodeCoverage::IPA_EXTENSIONS])
733 SAL_INFO("svtools", "IPA_EXTENSIONS");
734 if (rIn[vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS])
735 SAL_INFO("svtools", "SPACING_MODIFIER_LETTERS");
736 if (rIn[vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS])
737 SAL_INFO("svtools", "COMBINING_DIACRITICAL_MARKS");
738 if (rIn[vcl::UnicodeCoverage::GREEK_AND_COPTIC])
739 SAL_INFO("svtools", "GREEK_AND_COPTIC");
740 if (rIn[vcl::UnicodeCoverage::COPTIC])
741 SAL_INFO("svtools", "COPTIC");
742 if (rIn[vcl::UnicodeCoverage::CYRILLIC])
743 SAL_INFO("svtools", "CYRILLIC");
744 if (rIn[vcl::UnicodeCoverage::ARMENIAN])
745 SAL_INFO("svtools", "ARMENIAN");
746 if (rIn[vcl::UnicodeCoverage::HEBREW])
747 SAL_INFO("svtools", "HEBREW");
748 if (rIn[vcl::UnicodeCoverage::VAI])
749 SAL_INFO("svtools", "VAI");
750 if (rIn[vcl::UnicodeCoverage::ARABIC])
751 SAL_INFO("svtools", "ARABIC");
752 if (rIn[vcl::UnicodeCoverage::NKO])
753 SAL_INFO("svtools", "NKO");
754 if (rIn[vcl::UnicodeCoverage::DEVANAGARI])
755 SAL_INFO("svtools", "DEVANAGARI");
756 if (rIn[vcl::UnicodeCoverage::BENGALI])
757 SAL_INFO("svtools", "BENGALI");
758 if (rIn[vcl::UnicodeCoverage::GURMUKHI])
759 SAL_INFO("svtools", "GURMUKHI");
760 if (rIn[vcl::UnicodeCoverage::GUJARATI])
761 SAL_INFO("svtools", "GUJARATI");
762 if (rIn[vcl::UnicodeCoverage::ODIA])
763 SAL_INFO("svtools", "ODIA");
764 if (rIn[vcl::UnicodeCoverage::TAMIL])
765 SAL_INFO("svtools", "TAMIL");
766 if (rIn[vcl::UnicodeCoverage::TELUGU])
767 SAL_INFO("svtools", "TELUGU");
768 if (rIn[vcl::UnicodeCoverage::KANNADA])
769 SAL_INFO("svtools", "KANNADA");
770 if (rIn[vcl::UnicodeCoverage::MALAYALAM])
771 SAL_INFO("svtools", "MALAYALAM");
772 if (rIn[vcl::UnicodeCoverage::THAI])
773 SAL_INFO("svtools", "THAI");
774 if (rIn[vcl::UnicodeCoverage::LAO])
775 SAL_INFO("svtools", "LAO");
776 if (rIn[vcl::UnicodeCoverage::GEORGIAN])
777 SAL_INFO("svtools", "GEORGIAN");
778 if (rIn[vcl::UnicodeCoverage::BALINESE])
779 SAL_INFO("svtools", "BALINESE");
780 if (rIn[vcl::UnicodeCoverage::HANGUL_JAMO])
781 SAL_INFO("svtools", "HANGUL_JAMO");
782 if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL])
783 SAL_INFO("svtools", "LATIN_EXTENDED_ADDITIONAL");
784 if (rIn[vcl::UnicodeCoverage::GREEK_EXTENDED])
785 SAL_INFO("svtools", "GREEK_EXTENDED");
786 if (rIn[vcl::UnicodeCoverage::GENERAL_PUNCTUATION])
787 SAL_INFO("svtools", "GENERAL_PUNCTUATION");
788 if (rIn[vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS])
789 SAL_INFO("svtools", "SUPERSCRIPTS_AND_SUBSCRIPTS");
790 if (rIn[vcl::UnicodeCoverage::CURRENCY_SYMBOLS])
791 SAL_INFO("svtools", "CURRENCY_SYMBOLS");
792 if (rIn[vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS])
793 SAL_INFO("svtools", "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS");
794 if (rIn[vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS])
795 SAL_INFO("svtools", "LETTERLIKE_SYMBOLS");
796 if (rIn[vcl::UnicodeCoverage::NUMBER_FORMS])
797 SAL_INFO("svtools", "NUMBER_FORMS");
798 if (rIn[vcl::UnicodeCoverage::ARROWS])
799 SAL_INFO("svtools", "ARROWS");
800 if (rIn[vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS])
801 SAL_INFO("svtools", "MATHEMATICAL_OPERATORS");
802 if (rIn[vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL])
803 SAL_INFO("svtools", "MISCELLANEOUS_TECHNICAL");
804 if (rIn[vcl::UnicodeCoverage::CONTROL_PICTURES])
805 SAL_INFO("svtools", "CONTROL_PICTURES");
806 if (rIn[vcl::UnicodeCoverage::OPTICAL_CHARACTER_RECOGNITION])
807 SAL_INFO("svtools", "OPTICAL_CHARACTER_RECOGNITION");
808 if (rIn[vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS])
809 SAL_INFO("svtools", "ENCLOSED_ALPHANUMERICS");
810 if (rIn[vcl::UnicodeCoverage::BOX_DRAWING])
811 SAL_INFO("svtools", "BOX_DRAWING");
812 if (rIn[vcl::UnicodeCoverage::BLOCK_ELEMENTS])
813 SAL_INFO("svtools", "BLOCK_ELEMENTS");
814 if (rIn[vcl::UnicodeCoverage::GEOMETRIC_SHAPES])
815 SAL_INFO("svtools", "GEOMETRIC_SHAPES");
816 if (rIn[vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS])
817 SAL_INFO("svtools", "MISCELLANEOUS_SYMBOLS");
818 if (rIn[vcl::UnicodeCoverage::DINGBATS])
819 SAL_INFO("svtools", "DINGBATS");
820 if (rIn[vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION])
821 SAL_INFO("svtools", "CJK_SYMBOLS_AND_PUNCTUATION");
822 if (rIn[vcl::UnicodeCoverage::HIRAGANA])
823 SAL_INFO("svtools", "HIRAGANA");
824 if (rIn[vcl::UnicodeCoverage::KATAKANA])
825 SAL_INFO("svtools", "KATAKANA");
826 if (rIn[vcl::UnicodeCoverage::BOPOMOFO])
827 SAL_INFO("svtools", "BOPOMOFO");
828 if (rIn[vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO])
829 SAL_INFO("svtools", "HANGUL_COMPATIBILITY_JAMO");
830 if (rIn[vcl::UnicodeCoverage::PHAGS_PA])
831 SAL_INFO("svtools", "PHAGS_PA");
832 if (rIn[vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS])
833 SAL_INFO("svtools", "ENCLOSED_CJK_LETTERS_AND_MONTHS");
834 if (rIn[vcl::UnicodeCoverage::CJK_COMPATIBILITY])
835 SAL_INFO("svtools", "CJK_COMPATIBILITY");
836 if (rIn[vcl::UnicodeCoverage::HANGUL_SYLLABLES])
837 SAL_INFO("svtools", "HANGUL_SYLLABLES");
838 if (rIn[vcl::UnicodeCoverage::NONPLANE_0])
839 SAL_INFO("svtools", "NONPLANE_0");
840 if (rIn[vcl::UnicodeCoverage::PHOENICIAN])
841 SAL_INFO("svtools", "PHOENICIAN");
842 if (rIn[vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS])
843 SAL_INFO("svtools", "CJK_UNIFIED_IDEOGRAPHS");
844 if (rIn[vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0])
845 SAL_INFO("svtools", "PRIVATE_USE_AREA_PLANE_0");
846 if (rIn[vcl::UnicodeCoverage::CJK_STROKES])
847 SAL_INFO("svtools", "CJK_STROKES");
848 if (rIn[vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS])
849 SAL_INFO("svtools", "ALPHABETIC_PRESENTATION_FORMS");
850 if (rIn[vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A])
851 SAL_INFO("svtools", "ARABIC_PRESENTATION_FORMS_A");
852 if (rIn[vcl::UnicodeCoverage::COMBINING_HALF_MARKS])
853 SAL_INFO("svtools", "COMBINING_HALF_MARKS");
854 if (rIn[vcl::UnicodeCoverage::VERTICAL_FORMS])
855 SAL_INFO("svtools", "VERTICAL_FORMS");
856 if (rIn[vcl::UnicodeCoverage::SMALL_FORM_VARIANTS])
857 SAL_INFO("svtools", "SMALL_FORM_VARIANTS");
858 if (rIn[vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B])
859 SAL_INFO("svtools", "ARABIC_PRESENTATION_FORMS_B");
860 if (rIn[vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS])
861 SAL_INFO("svtools", "HALFWIDTH_AND_FULLWIDTH_FORMS");
862 if (rIn[vcl::UnicodeCoverage::SPECIALS])
863 SAL_INFO("svtools", "SPECIALS");
864 if (rIn[vcl::UnicodeCoverage::TIBETAN])
865 SAL_INFO("svtools", "TIBETAN");
866 if (rIn[vcl::UnicodeCoverage::SYRIAC])
867 SAL_INFO("svtools", "SYRIAC");
868 if (rIn[vcl::UnicodeCoverage::THAANA])
869 SAL_INFO("svtools", "THAANA");
870 if (rIn[vcl::UnicodeCoverage::SINHALA])
871 SAL_INFO("svtools", "SINHALA");
872 if (rIn[vcl::UnicodeCoverage::MYANMAR])
873 SAL_INFO("svtools", "MYANMAR");
874 if (rIn[vcl::UnicodeCoverage::ETHIOPIC])
875 SAL_INFO("svtools", "ETHIOPIC");
876 if (rIn[vcl::UnicodeCoverage::CHEROKEE])
877 SAL_INFO("svtools", "CHEROKEE");
878 if (rIn[vcl::UnicodeCoverage::UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS])
879 SAL_INFO("svtools", "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS");
880 if (rIn[vcl::UnicodeCoverage::OGHAM])
881 SAL_INFO("svtools", "OGHAM");
882 if (rIn[vcl::UnicodeCoverage::RUNIC])
883 SAL_INFO("svtools", "RUNIC");
884 if (rIn[vcl::UnicodeCoverage::KHMER])
885 SAL_INFO("svtools", "KHMER");
886 if (rIn[vcl::UnicodeCoverage::MONGOLIAN])
887 SAL_INFO("svtools", "MONGOLIAN");
888 if (rIn[vcl::UnicodeCoverage::BRAILLE_PATTERNS])
889 SAL_INFO("svtools", "BRAILLE_PATTERNS");
890 if (rIn[vcl::UnicodeCoverage::YI_SYLLABLES])
891 SAL_INFO("svtools", "YI_SYLLABLES");
892 if (rIn[vcl::UnicodeCoverage::TAGALOG])
893 SAL_INFO("svtools", "TAGALOG");
894 if (rIn[vcl::UnicodeCoverage::OLD_ITALIC])
895 SAL_INFO("svtools", "OLD_ITALIC");
896 if (rIn[vcl::UnicodeCoverage::GOTHIC])
897 SAL_INFO("svtools", "GOTHIC");
898 if (rIn[vcl::UnicodeCoverage::DESERET])
899 SAL_INFO("svtools", "DESERET");
900 if (rIn[vcl::UnicodeCoverage::BYZANTINE_MUSICAL_SYMBOLS])
901 SAL_INFO("svtools", "BYZANTINE_MUSICAL_SYMBOLS");
902 if (rIn[vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS])
903 SAL_INFO("svtools", "MATHEMATICAL_ALPHANUMERIC_SYMBOLS");
904 if (rIn[vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15])
905 SAL_INFO("svtools", "PRIVATE_USE_PLANE_15");
906 if (rIn[vcl::UnicodeCoverage::VARIATION_SELECTORS])
907 SAL_INFO("svtools", "VARIATION_SELECTORS");
908 if (rIn[vcl::UnicodeCoverage::TAGS])
909 SAL_INFO("svtools", "TAGS");
910 if (rIn[vcl::UnicodeCoverage::LIMBU])
911 SAL_INFO("svtools", "LIMBU");
912 if (rIn[vcl::UnicodeCoverage::TAI_LE])
913 SAL_INFO("svtools", "TAI_LE");
914 if (rIn[vcl::UnicodeCoverage::NEW_TAI_LUE])
915 SAL_INFO("svtools", "NEW_TAI_LUE");
916 if (rIn[vcl::UnicodeCoverage::BUGINESE])
917 SAL_INFO("svtools", "BUGINESE");
918 if (rIn[vcl::UnicodeCoverage::GLAGOLITIC])
919 SAL_INFO("svtools", "GLAGOLITIC");
920 if (rIn[vcl::UnicodeCoverage::TIFINAGH])
921 SAL_INFO("svtools", "TIFINAGH");
922 if (rIn[vcl::UnicodeCoverage::YIJING_HEXAGRAM_SYMBOLS])
923 SAL_INFO("svtools", "YIJING_HEXAGRAM_SYMBOLS");
924 if (rIn[vcl::UnicodeCoverage::SYLOTI_NAGRI])
925 SAL_INFO("svtools", "SYLOTI_NAGRI");
926 if (rIn[vcl::UnicodeCoverage::LINEAR_B_SYLLABARY])
927 SAL_INFO("svtools", "LINEAR_B_SYLLABARY");
928 if (rIn[vcl::UnicodeCoverage::ANCIENT_GREEK_NUMBERS])
929 SAL_INFO("svtools", "ANCIENT_GREEK_NUMBERS");
930 if (rIn[vcl::UnicodeCoverage::UGARITIC])
931 SAL_INFO("svtools", "UGARITIC");
932 if (rIn[vcl::UnicodeCoverage::OLD_PERSIAN])
933 SAL_INFO("svtools", "OLD_PERSIAN");
934 if (rIn[vcl::UnicodeCoverage::SHAVIAN])
935 SAL_INFO("svtools", "SHAVIAN");
936 if (rIn[vcl::UnicodeCoverage::OSMANYA])
937 SAL_INFO("svtools", "OSMANYA");
938 if (rIn[vcl::UnicodeCoverage::CYPRIOT_SYLLABARY])
939 SAL_INFO("svtools", "CYPRIOT_SYLLABARY");
940 if (rIn[vcl::UnicodeCoverage::KHAROSHTHI])
941 SAL_INFO("svtools", "KHAROSHTHI");
942 if (rIn[vcl::UnicodeCoverage::TAI_XUAN_JING_SYMBOLS])
943 SAL_INFO("svtools", "TAI_XUAN_JING_SYMBOLS");
944 if (rIn[vcl::UnicodeCoverage::CUNEIFORM])
945 SAL_INFO("svtools", "CUNEIFORM");
946 if (rIn[vcl::UnicodeCoverage::COUNTING_ROD_NUMERALS])
947 SAL_INFO("svtools", "COUNTING_ROD_NUMERALS");
948 if (rIn[vcl::UnicodeCoverage::SUNDANESE])
949 SAL_INFO("svtools", "SUNDANESE");
950 if (rIn[vcl::UnicodeCoverage::LEPCHA])
951 SAL_INFO("svtools", "LEPCHA");
952 if (rIn[vcl::UnicodeCoverage::OL_CHIKI])
953 SAL_INFO("svtools", "OL_CHIKI");
954 if (rIn[vcl::UnicodeCoverage::SAURASHTRA])
955 SAL_INFO("svtools", "SAURASHTRA");
956 if (rIn[vcl::UnicodeCoverage::KAYAH_LI])
957 SAL_INFO("svtools", "KAYAH_LI");
958 if (rIn[vcl::UnicodeCoverage::REJANG])
959 SAL_INFO("svtools", "REJANG");
960 if (rIn[vcl::UnicodeCoverage::CHAM])
961 SAL_INFO("svtools", "CHAM");
962 if (rIn[vcl::UnicodeCoverage::ANCIENT_SYMBOLS])
963 SAL_INFO("svtools", "ANCIENT_SYMBOLS");
964 if (rIn[vcl::UnicodeCoverage::PHAISTOS_DISC])
965 SAL_INFO("svtools", "PHAISTOS_DISC");
966 if (rIn[vcl::UnicodeCoverage::CARIAN])
967 SAL_INFO("svtools", "CARIAN");
968 if (rIn[vcl::UnicodeCoverage::DOMINO_TILES])
969 SAL_INFO("svtools", "DOMINO_TILES");
970 if (rIn[vcl::UnicodeCoverage::RESERVED1])
971 SAL_INFO("svtools", "RESERVED1");
972 if (rIn[vcl::UnicodeCoverage::RESERVED2])
973 SAL_INFO("svtools", "RESERVED2");
974 if (rIn[vcl::UnicodeCoverage::RESERVED3])
975 SAL_INFO("svtools", "RESERVED3");
976 if (rIn[vcl::UnicodeCoverage::RESERVED4])
977 SAL_INFO("svtools", "RESERVED4");
978 if (rIn[vcl::UnicodeCoverage::RESERVED5])
979 SAL_INFO("svtools", "RESERVED5");
982 void lcl_dump_codepage_coverage(const std::optional<std::bitset<vcl::CodePageCoverage::MAX_CP_ENUM>> &roIn)
984 if (!roIn)
986 SAL_INFO("svtools", "<NOTHING>");
987 return;
989 auto & rIn(*roIn);
990 if (rIn.none())
992 SAL_INFO("svtools", "<NONE>");
993 return;
995 if (rIn[vcl::CodePageCoverage::CP1252])
996 SAL_INFO("svtools", "CP1252");
997 if (rIn[vcl::CodePageCoverage::CP1250])
998 SAL_INFO("svtools", "CP1250");
999 if (rIn[vcl::CodePageCoverage::CP1251])
1000 SAL_INFO("svtools", "CP1251");
1001 if (rIn[vcl::CodePageCoverage::CP1253])
1002 SAL_INFO("svtools", "CP1253");
1003 if (rIn[vcl::CodePageCoverage::CP1254])
1004 SAL_INFO("svtools", "CP1254");
1005 if (rIn[vcl::CodePageCoverage::CP1255])
1006 SAL_INFO("svtools", "CP1255");
1007 if (rIn[vcl::CodePageCoverage::CP1256])
1008 SAL_INFO("svtools", "CP1256");
1009 if (rIn[vcl::CodePageCoverage::CP1257])
1010 SAL_INFO("svtools", "CP1257");
1011 if (rIn[vcl::CodePageCoverage::CP1258])
1012 SAL_INFO("svtools", "CP1258");
1013 if (rIn[vcl::CodePageCoverage::CP874])
1014 SAL_INFO("svtools", "CP874");
1015 if (rIn[vcl::CodePageCoverage::CP932])
1016 SAL_INFO("svtools", "CP932");
1017 if (rIn[vcl::CodePageCoverage::CP936])
1018 SAL_INFO("svtools", "CP936");
1019 if (rIn[vcl::CodePageCoverage::CP949])
1020 SAL_INFO("svtools", "CP949");
1021 if (rIn[vcl::CodePageCoverage::CP950])
1022 SAL_INFO("svtools", "CP950");
1023 if (rIn[vcl::CodePageCoverage::CP1361])
1024 SAL_INFO("svtools", "CP1361");
1025 if (rIn[vcl::CodePageCoverage::CP869])
1026 SAL_INFO("svtools", "CP869");
1027 if (rIn[vcl::CodePageCoverage::CP866])
1028 SAL_INFO("svtools", "CP866");
1029 if (rIn[vcl::CodePageCoverage::CP865])
1030 SAL_INFO("svtools", "CP865");
1031 if (rIn[vcl::CodePageCoverage::CP864])
1032 SAL_INFO("svtools", "CP864");
1033 if (rIn[vcl::CodePageCoverage::CP863])
1034 SAL_INFO("svtools", "CP863");
1035 if (rIn[vcl::CodePageCoverage::CP862])
1036 SAL_INFO("svtools", "CP862");
1037 if (rIn[vcl::CodePageCoverage::CP861])
1038 SAL_INFO("svtools", "CP861");
1039 if (rIn[vcl::CodePageCoverage::CP860])
1040 SAL_INFO("svtools", "CP860");
1041 if (rIn[vcl::CodePageCoverage::CP857])
1042 SAL_INFO("svtools", "CP857");
1043 if (rIn[vcl::CodePageCoverage::CP855])
1044 SAL_INFO("svtools", "CP855");
1045 if (rIn[vcl::CodePageCoverage::CP852])
1046 SAL_INFO("svtools", "CP852");
1047 if (rIn[vcl::CodePageCoverage::CP775])
1048 SAL_INFO("svtools", "CP775");
1049 if (rIn[vcl::CodePageCoverage::CP737])
1050 SAL_INFO("svtools", "CP737");
1051 if (rIn[vcl::CodePageCoverage::CP780])
1052 SAL_INFO("svtools", "CP780");
1053 if (rIn[vcl::CodePageCoverage::CP850])
1054 SAL_INFO("svtools", "CP850");
1055 if (rIn[vcl::CodePageCoverage::CP437])
1056 SAL_INFO("svtools", "CP437");
1058 #endif
1060 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> getMaskByScriptType(sal_Int16 nScriptType)
1062 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> aMask;
1063 aMask.set();
1065 for (size_t i = 0; i < vcl::UnicodeCoverage::MAX_UC_ENUM; ++i)
1067 using vcl::UnicodeCoverage::UnicodeCoverageEnum;
1068 UScriptCode eScriptCode = otCoverageToScript(static_cast<UnicodeCoverageEnum>(i));
1069 if (unicode::getScriptClassFromUScriptCode(eScriptCode) == nScriptType)
1070 aMask.set(i, false);
1073 return aMask;
1076 //false for all bits considered "Latin" by LibreOffice
1077 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getLatinMask()
1079 static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::LATIN));
1080 return s_Mask;
1083 //false for all bits considered "Asian" by LibreOffice
1084 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getCJKMask()
1086 static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::ASIAN));
1087 return s_Mask;
1090 //false for all bits considered "Complex" by LibreOffice
1091 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getCTLMask()
1093 static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::COMPLEX));
1094 return s_Mask;
1097 //false for all bits considered "WEAK" by LibreOffice
1098 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> const & getWeakMask()
1100 static std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> s_Mask(getMaskByScriptType(css::i18n::ScriptType::WEAK));
1101 return s_Mask;
1104 //Nearly every font supports some basic Latin
1105 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> getCommonLatnSubsetMask()
1107 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> aMask;
1108 aMask.set();
1109 aMask.set(vcl::UnicodeCoverage::BASIC_LATIN, false);
1110 aMask.set(vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT, false);
1111 aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_A, false);
1112 aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_B, false);
1113 aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL, false);
1114 return aMask;
1117 template<size_t N>
1118 size_t find_first(std::bitset<N> const& rSet)
1120 for (size_t i = 0; i < N; ++i)
1122 if (rSet.test(i))
1123 return i;
1125 assert(false); // see current usage
1126 return N;
1129 UScriptCode getScript(const vcl::FontCapabilities &rFontCapabilities)
1131 using vcl::UnicodeCoverage::UnicodeCoverageEnum;
1133 std::bitset<vcl::UnicodeCoverage::MAX_UC_ENUM> aMasked;
1134 if (rFontCapabilities.oUnicodeRange)
1136 aMasked = *rFontCapabilities.oUnicodeRange & getWeakMask();
1139 if (aMasked.count() == 1)
1140 return otCoverageToScript(static_cast<UnicodeCoverageEnum>(find_first(aMasked)));
1142 if (aMasked[vcl::UnicodeCoverage::ARABIC])
1144 aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A, false);
1145 aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B, false);
1146 aMasked.set(vcl::UnicodeCoverage::NKO, false);
1147 //Probably strongly tuned for Arabic
1148 if (aMasked.count() == 1)
1149 return USCRIPT_ARABIC;
1150 if (aMasked.count() == 2 && aMasked[vcl::UnicodeCoverage::SYRIAC])
1151 return USCRIPT_SYRIAC;
1154 if (aMasked[vcl::UnicodeCoverage::DEVANAGARI])
1156 aMasked.set(vcl::UnicodeCoverage::DEVANAGARI, false);
1157 //Probably strongly tuned for a single Indic script
1158 if (aMasked.count() == 1)
1159 return otCoverageToScript(static_cast<UnicodeCoverageEnum>(find_first(aMasked)));
1162 aMasked.set(vcl::UnicodeCoverage::GREEK_EXTENDED, false);
1163 aMasked.set(vcl::UnicodeCoverage::GREEK_AND_COPTIC, false);
1164 if (aMasked.count() == 1)
1165 return otCoverageToScript(static_cast<UnicodeCoverageEnum>(find_first(aMasked)));
1167 if (aMasked[vcl::UnicodeCoverage::CYRILLIC])
1169 //Probably strongly tuned for Georgian
1170 if (aMasked.count() == 2 && aMasked[vcl::UnicodeCoverage::GEORGIAN])
1171 return USCRIPT_GEORGIAN;
1174 aMasked &= getCJKMask();
1176 aMasked.set(vcl::UnicodeCoverage::CYRILLIC, false);
1177 aMasked.set(vcl::UnicodeCoverage::THAI, false);
1178 aMasked.set(vcl::UnicodeCoverage::DESERET, false);
1179 aMasked.set(vcl::UnicodeCoverage::PHAGS_PA, false);
1181 //So, possibly a CJK font
1182 if (!aMasked.count() && rFontCapabilities.oCodePageRange)
1184 std::bitset<vcl::CodePageCoverage::MAX_CP_ENUM> aCJKCodePageMask;
1185 aCJKCodePageMask.set(vcl::CodePageCoverage::CP932);
1186 aCJKCodePageMask.set(vcl::CodePageCoverage::CP936);
1187 aCJKCodePageMask.set(vcl::CodePageCoverage::CP949);
1188 aCJKCodePageMask.set(vcl::CodePageCoverage::CP950);
1189 aCJKCodePageMask.set(vcl::CodePageCoverage::CP1361);
1190 std::bitset<vcl::CodePageCoverage::MAX_CP_ENUM> aMaskedCodePage =
1191 *rFontCapabilities.oCodePageRange & aCJKCodePageMask;
1192 //fold Korean
1193 if (aMaskedCodePage[vcl::CodePageCoverage::CP1361])
1195 aMaskedCodePage.set(vcl::CodePageCoverage::CP949);
1196 aMaskedCodePage.set(vcl::CodePageCoverage::CP1361, false);
1199 if (aMaskedCodePage.count() == 1)
1201 if (aMaskedCodePage[vcl::CodePageCoverage::CP932])
1202 return USCRIPT_JAPANESE;
1203 if (aMaskedCodePage[vcl::CodePageCoverage::CP949])
1204 return USCRIPT_KOREAN;
1205 if (aMaskedCodePage[vcl::CodePageCoverage::CP936])
1206 return USCRIPT_SIMPLIFIED_HAN;
1207 if (aMaskedCodePage[vcl::CodePageCoverage::CP950])
1208 return USCRIPT_TRADITIONAL_HAN;
1211 if (aMaskedCodePage.count())
1212 return USCRIPT_HAN;
1215 return USCRIPT_COMMON;
1219 const std::map<UScriptCode, std::vector<OUString>> distCjkMap =
1221 { USCRIPT_KOREAN, { " KR", "Korean"} }, // Korean
1222 { USCRIPT_JAPANESE, {" JP", "Japanese"} } , // Japanese
1223 { USCRIPT_SIMPLIFIED_HAN, {" SC", " GB", "S Chinese"} }, // Simplified Chinese Family
1224 { USCRIPT_TRADITIONAL_HAN, {" TC", " HC", " TW", " HK", " MO", "T Chinese"} }// Traditional Chinese Family
1226 namespace
1228 UScriptCode attemptToDisambiguateHan(UScriptCode eScript, OutputDevice const &rDevice)
1230 //If we're a CJK font, see if we seem to be tuned for C, J or K
1231 if (eScript == USCRIPT_HAN)
1233 const vcl::Font &rFont = rDevice.GetFont();
1235 bool bKore = false, bJpan = false, bHant = false, bHans = false;
1237 static const sal_Unicode aKorean[] = { 0x4E6D, 0x4E76, 0x596C };
1238 OUString sKorean(aKorean, SAL_N_ELEMENTS(aKorean));
1239 if (-1 == rDevice.HasGlyphs(rFont, sKorean))
1240 bKore = true;
1242 static const sal_Unicode aJapanese[] = { 0x5968, 0x67A0, 0x9D8F };
1243 OUString sJapanese(aJapanese, SAL_N_ELEMENTS(aJapanese));
1244 if (-1 == rDevice.HasGlyphs(rFont, sJapanese))
1245 bJpan = true;
1247 static const sal_Unicode aTraditionalChinese[] = { 0x555F, 0x96DE };
1248 OUString sTraditionalChinese(aTraditionalChinese, SAL_N_ELEMENTS(aTraditionalChinese));
1249 if (-1 == rDevice.HasGlyphs(rFont, sTraditionalChinese))
1250 bHant = true;
1252 static const sal_Unicode aSimplifiedChinese[] = { 0x4E61, 0x542F, 0x5956 };
1253 OUString sSimplifiedChinese(aSimplifiedChinese, SAL_N_ELEMENTS(aSimplifiedChinese));
1254 if (-1 == rDevice.HasGlyphs(rFont, sSimplifiedChinese))
1255 bHans = true;
1257 if (bKore && !bJpan && !bHans && !bHant) {
1258 eScript = USCRIPT_KOREAN;
1259 return eScript;
1261 else if (bJpan && !bKore && !bHans && !bHant) {
1262 eScript = USCRIPT_JAPANESE;
1263 return eScript;
1265 else if (bHans && !bHant && !bKore && !bJpan) {
1266 eScript = USCRIPT_SIMPLIFIED_HAN;
1267 return eScript;
1269 else if (bHant && !bHans && !bKore && !bJpan) {
1270 eScript = USCRIPT_TRADITIONAL_HAN;
1271 return eScript;
1274 // for the last time, Check the ISO code strings or font specific strings
1275 const OUString &rName = rDevice.GetFont().GetFamilyName();
1276 std::map<UScriptCode, std::vector<OUString>>::const_iterator distCjkMapIt;
1277 for (distCjkMapIt = distCjkMap.begin(); distCjkMapIt != distCjkMap.end(); ++distCjkMapIt) {
1278 std::vector<OUString> cjkCodeList = distCjkMapIt->second;
1279 std::vector<OUString>::const_iterator cjkPtr;
1280 for (cjkPtr = cjkCodeList.begin(); cjkPtr != cjkCodeList.end(); ++cjkPtr) {
1281 if (rName.indexOf(*cjkPtr) > 0) {
1282 return distCjkMapIt->first;
1286 //otherwise fall-through as USCRIPT_HAN and expect a combined Hant/Hans preview
1288 return eScript;
1292 OUString makeShortRepresentativeTextForSelectedFont(OutputDevice const &rDevice)
1294 UScriptCode eScript = lcl_getHardCodedScriptNameForFont(rDevice);
1295 if (eScript == USCRIPT_INVALID_CODE)
1297 vcl::FontCapabilities aFontCapabilities;
1298 if (!rDevice.GetFontCapabilities(aFontCapabilities))
1299 return OUString();
1301 #if OSL_DEBUG_LEVEL > 0
1302 lcl_dump_unicode_coverage(aFontCapabilities.oUnicodeRange);
1303 lcl_dump_codepage_coverage(aFontCapabilities.oCodePageRange);
1304 #endif
1306 if (aFontCapabilities.oUnicodeRange)
1307 *aFontCapabilities.oUnicodeRange &= getCommonLatnSubsetMask();
1309 //If this font is probably tuned to display a single non-Latin
1310 //script and the font name is itself in Latin, then show a small
1311 //chunk of representative text for that script
1312 eScript = getScript(aFontCapabilities);
1313 if (eScript == USCRIPT_COMMON)
1314 return OUString();
1316 eScript = attemptToDisambiguateHan(eScript, rDevice);
1319 OUString sSampleText = makeShortRepresentativeTextForScript(eScript);
1320 bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText));
1321 return bHasSampleTextGlyphs ? sSampleText : OUString();
1324 UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCoverageEnum eOTCoverage)
1326 UScriptCode eRet = USCRIPT_COMMON;
1327 switch (eOTCoverage)
1329 case vcl::UnicodeCoverage::BASIC_LATIN:
1330 case vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT:
1331 case vcl::UnicodeCoverage::LATIN_EXTENDED_A:
1332 case vcl::UnicodeCoverage::LATIN_EXTENDED_B:
1333 eRet = USCRIPT_LATIN;
1334 break;
1335 case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS:
1336 eRet = USCRIPT_INHERITED;
1337 break;
1338 case vcl::UnicodeCoverage::GREEK_AND_COPTIC:
1339 eRet = USCRIPT_GREEK;
1340 break;
1341 case vcl::UnicodeCoverage::COPTIC:
1342 eRet = USCRIPT_COPTIC;
1343 break;
1344 case vcl::UnicodeCoverage::CYRILLIC:
1345 eRet = USCRIPT_CYRILLIC;
1346 break;
1347 case vcl::UnicodeCoverage::ARMENIAN:
1348 eRet = USCRIPT_ARMENIAN;
1349 break;
1350 case vcl::UnicodeCoverage::HEBREW:
1351 eRet = USCRIPT_HEBREW;
1352 break;
1353 case vcl::UnicodeCoverage::VAI:
1354 eRet = USCRIPT_VAI;
1355 break;
1356 case vcl::UnicodeCoverage::ARABIC:
1357 eRet = USCRIPT_ARABIC;
1358 break;
1359 case vcl::UnicodeCoverage::NKO:
1360 eRet = USCRIPT_NKO;
1361 break;
1362 case vcl::UnicodeCoverage::DEVANAGARI:
1363 eRet = USCRIPT_DEVANAGARI;
1364 break;
1365 case vcl::UnicodeCoverage::BENGALI:
1366 eRet = USCRIPT_BENGALI;
1367 break;
1368 case vcl::UnicodeCoverage::GURMUKHI:
1369 eRet = USCRIPT_GURMUKHI;
1370 break;
1371 case vcl::UnicodeCoverage::GUJARATI:
1372 eRet = USCRIPT_GUJARATI;
1373 break;
1374 case vcl::UnicodeCoverage::ODIA:
1375 eRet = USCRIPT_ORIYA;
1376 break;
1377 case vcl::UnicodeCoverage::TAMIL:
1378 eRet = USCRIPT_TAMIL;
1379 break;
1380 case vcl::UnicodeCoverage::TELUGU:
1381 eRet = USCRIPT_TELUGU;
1382 break;
1383 case vcl::UnicodeCoverage::KANNADA:
1384 eRet = USCRIPT_KANNADA;
1385 break;
1386 case vcl::UnicodeCoverage::MALAYALAM:
1387 eRet = USCRIPT_MALAYALAM;
1388 break;
1389 case vcl::UnicodeCoverage::THAI:
1390 eRet = USCRIPT_THAI;
1391 break;
1392 case vcl::UnicodeCoverage::LAO:
1393 eRet = USCRIPT_LAO;
1394 break;
1395 case vcl::UnicodeCoverage::GEORGIAN:
1396 eRet = USCRIPT_GEORGIAN;
1397 break;
1398 case vcl::UnicodeCoverage::BALINESE:
1399 eRet = USCRIPT_BALINESE;
1400 break;
1401 case vcl::UnicodeCoverage::HANGUL_JAMO:
1402 eRet = USCRIPT_HANGUL;
1403 break;
1404 case vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL:
1405 eRet = USCRIPT_LATIN;
1406 break;
1407 case vcl::UnicodeCoverage::GREEK_EXTENDED:
1408 eRet = USCRIPT_GREEK;
1409 break;
1410 case vcl::UnicodeCoverage::CURRENCY_SYMBOLS:
1411 eRet = USCRIPT_SYMBOLS;
1412 break;
1413 case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS:
1414 eRet = USCRIPT_INHERITED;
1415 break;
1416 case vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS:
1417 case vcl::UnicodeCoverage::NUMBER_FORMS:
1418 case vcl::UnicodeCoverage::ARROWS:
1419 eRet = USCRIPT_SYMBOLS;
1420 break;
1421 case vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS:
1422 eRet = USCRIPT_MATHEMATICAL_NOTATION;
1423 break;
1424 case vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL:
1425 case vcl::UnicodeCoverage::OPTICAL_CHARACTER_RECOGNITION:
1426 case vcl::UnicodeCoverage::BOX_DRAWING:
1427 case vcl::UnicodeCoverage::BLOCK_ELEMENTS:
1428 case vcl::UnicodeCoverage::GEOMETRIC_SHAPES:
1429 case vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS:
1430 case vcl::UnicodeCoverage::DINGBATS:
1431 case vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION:
1432 eRet = USCRIPT_SYMBOLS;
1433 break;
1434 case vcl::UnicodeCoverage::HIRAGANA:
1435 eRet = USCRIPT_HIRAGANA;
1436 break;
1437 case vcl::UnicodeCoverage::KATAKANA:
1438 eRet = USCRIPT_KATAKANA;
1439 break;
1440 case vcl::UnicodeCoverage::BOPOMOFO:
1441 eRet = USCRIPT_BOPOMOFO;
1442 break;
1443 case vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO:
1444 eRet = USCRIPT_HANGUL;
1445 break;
1446 case vcl::UnicodeCoverage::PHAGS_PA:
1447 eRet = USCRIPT_PHAGS_PA;
1448 break;
1449 case vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS:
1450 eRet = USCRIPT_HANGUL;
1451 break;
1452 case vcl::UnicodeCoverage::CJK_COMPATIBILITY:
1453 eRet = USCRIPT_HAN;
1454 break;
1455 case vcl::UnicodeCoverage::HANGUL_SYLLABLES:
1456 eRet = USCRIPT_HANGUL;
1457 break;
1458 case vcl::UnicodeCoverage::PHOENICIAN:
1459 eRet = USCRIPT_PHOENICIAN;
1460 break;
1461 case vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS:
1462 case vcl::UnicodeCoverage::CJK_STROKES:
1463 eRet = USCRIPT_HAN;
1464 break;
1465 case vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A:
1466 eRet = USCRIPT_ARABIC;
1467 break;
1468 case vcl::UnicodeCoverage::COMBINING_HALF_MARKS:
1469 eRet = USCRIPT_INHERITED;
1470 break;
1471 case vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B:
1472 eRet = USCRIPT_ARABIC;
1473 break;
1474 case vcl::UnicodeCoverage::TIBETAN:
1475 eRet = USCRIPT_TIBETAN;
1476 break;
1477 case vcl::UnicodeCoverage::SYRIAC:
1478 eRet = USCRIPT_SYRIAC;
1479 break;
1480 case vcl::UnicodeCoverage::THAANA:
1481 eRet = USCRIPT_THAANA;
1482 break;
1483 case vcl::UnicodeCoverage::SINHALA:
1484 eRet = USCRIPT_SINHALA;
1485 break;
1486 case vcl::UnicodeCoverage::MYANMAR:
1487 eRet = USCRIPT_MYANMAR;
1488 break;
1489 case vcl::UnicodeCoverage::ETHIOPIC:
1490 eRet = USCRIPT_ETHIOPIC;
1491 break;
1492 case vcl::UnicodeCoverage::CHEROKEE:
1493 eRet = USCRIPT_CHEROKEE;
1494 break;
1495 case vcl::UnicodeCoverage::UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS:
1496 eRet = USCRIPT_CANADIAN_ABORIGINAL;
1497 break;
1498 case vcl::UnicodeCoverage::OGHAM:
1499 eRet = USCRIPT_OGHAM;
1500 break;
1501 case vcl::UnicodeCoverage::RUNIC:
1502 eRet = USCRIPT_RUNIC;
1503 break;
1504 case vcl::UnicodeCoverage::KHMER:
1505 eRet = USCRIPT_KHMER;
1506 break;
1507 case vcl::UnicodeCoverage::MONGOLIAN:
1508 eRet = USCRIPT_MONGOLIAN;
1509 break;
1510 case vcl::UnicodeCoverage::BRAILLE_PATTERNS:
1511 eRet = USCRIPT_BRAILLE;
1512 break;
1513 case vcl::UnicodeCoverage::YI_SYLLABLES:
1514 eRet = USCRIPT_YI;
1515 break;
1516 case vcl::UnicodeCoverage::TAGALOG:
1517 eRet = USCRIPT_TAGALOG;
1518 break;
1519 case vcl::UnicodeCoverage::OLD_ITALIC:
1520 eRet = USCRIPT_OLD_ITALIC;
1521 break;
1522 case vcl::UnicodeCoverage::GOTHIC:
1523 eRet = USCRIPT_GOTHIC;
1524 break;
1525 case vcl::UnicodeCoverage::DESERET:
1526 eRet = USCRIPT_DESERET;
1527 break;
1528 case vcl::UnicodeCoverage::BYZANTINE_MUSICAL_SYMBOLS:
1529 case vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS:
1530 case vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15:
1531 eRet = USCRIPT_SYMBOLS;
1532 break;
1533 case vcl::UnicodeCoverage::VARIATION_SELECTORS:
1534 eRet = USCRIPT_INHERITED;
1535 break;
1536 case vcl::UnicodeCoverage::TAGS:
1537 eRet = USCRIPT_SYMBOLS;
1538 break;
1539 case vcl::UnicodeCoverage::LIMBU:
1540 eRet = USCRIPT_LIMBU;
1541 break;
1542 case vcl::UnicodeCoverage::TAI_LE:
1543 eRet = USCRIPT_TAI_LE;
1544 break;
1545 case vcl::UnicodeCoverage::NEW_TAI_LUE:
1546 eRet = USCRIPT_NEW_TAI_LUE;
1547 break;
1548 case vcl::UnicodeCoverage::BUGINESE:
1549 eRet = USCRIPT_BUGINESE;
1550 break;
1551 case vcl::UnicodeCoverage::GLAGOLITIC:
1552 eRet = USCRIPT_GLAGOLITIC;
1553 break;
1554 case vcl::UnicodeCoverage::TIFINAGH:
1555 eRet = USCRIPT_TIFINAGH;
1556 break;
1557 case vcl::UnicodeCoverage::YIJING_HEXAGRAM_SYMBOLS:
1558 eRet = USCRIPT_SYMBOLS;
1559 break;
1560 case vcl::UnicodeCoverage::SYLOTI_NAGRI:
1561 eRet = USCRIPT_SYLOTI_NAGRI;
1562 break;
1563 case vcl::UnicodeCoverage::LINEAR_B_SYLLABARY:
1564 eRet = USCRIPT_LINEAR_B;
1565 break;
1566 case vcl::UnicodeCoverage::ANCIENT_GREEK_NUMBERS:
1567 eRet = USCRIPT_GREEK;
1568 break;
1569 case vcl::UnicodeCoverage::UGARITIC:
1570 eRet = USCRIPT_UGARITIC;
1571 break;
1572 case vcl::UnicodeCoverage::OLD_PERSIAN:
1573 eRet = USCRIPT_OLD_PERSIAN;
1574 break;
1575 case vcl::UnicodeCoverage::SHAVIAN:
1576 eRet = USCRIPT_SHAVIAN;
1577 break;
1578 case vcl::UnicodeCoverage::OSMANYA:
1579 eRet = USCRIPT_OSMANYA;
1580 break;
1581 case vcl::UnicodeCoverage::CYPRIOT_SYLLABARY:
1582 eRet = USCRIPT_CYPRIOT;
1583 break;
1584 case vcl::UnicodeCoverage::KHAROSHTHI:
1585 eRet = USCRIPT_KHAROSHTHI;
1586 break;
1587 case vcl::UnicodeCoverage::CUNEIFORM:
1588 eRet = USCRIPT_CUNEIFORM;
1589 break;
1590 case vcl::UnicodeCoverage::SUNDANESE:
1591 eRet = USCRIPT_SUNDANESE;
1592 break;
1593 case vcl::UnicodeCoverage::LEPCHA:
1594 eRet = USCRIPT_LEPCHA;
1595 break;
1596 case vcl::UnicodeCoverage::OL_CHIKI:
1597 eRet = USCRIPT_OL_CHIKI;
1598 break;
1599 case vcl::UnicodeCoverage::SAURASHTRA:
1600 eRet = USCRIPT_SAURASHTRA;
1601 break;
1602 case vcl::UnicodeCoverage::KAYAH_LI:
1603 eRet = USCRIPT_KAYAH_LI;
1604 break;
1605 case vcl::UnicodeCoverage::REJANG:
1606 eRet = USCRIPT_REJANG;
1607 break;
1608 case vcl::UnicodeCoverage::CHAM:
1609 eRet = USCRIPT_CHAM;
1610 break;
1611 case vcl::UnicodeCoverage::CARIAN:
1612 eRet = USCRIPT_CARIAN;
1613 break;
1614 case vcl::UnicodeCoverage::DOMINO_TILES:
1615 case vcl::UnicodeCoverage::TAI_XUAN_JING_SYMBOLS:
1616 case vcl::UnicodeCoverage::COUNTING_ROD_NUMERALS:
1617 case vcl::UnicodeCoverage::ANCIENT_SYMBOLS:
1618 case vcl::UnicodeCoverage::PHAISTOS_DISC:
1619 eRet = USCRIPT_SYMBOLS;
1620 break;
1621 case vcl::UnicodeCoverage::IPA_EXTENSIONS:
1622 case vcl::UnicodeCoverage::SPECIALS:
1623 case vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS:
1624 case vcl::UnicodeCoverage::VERTICAL_FORMS:
1625 case vcl::UnicodeCoverage::SMALL_FORM_VARIANTS:
1626 case vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS:
1627 case vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0:
1628 case vcl::UnicodeCoverage::NONPLANE_0:
1629 case vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS:
1630 case vcl::UnicodeCoverage::CONTROL_PICTURES:
1631 case vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS:
1632 case vcl::UnicodeCoverage::GENERAL_PUNCTUATION:
1633 case vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS:
1634 case vcl::UnicodeCoverage::RESERVED1:
1635 case vcl::UnicodeCoverage::RESERVED2:
1636 case vcl::UnicodeCoverage::RESERVED3:
1637 case vcl::UnicodeCoverage::RESERVED4:
1638 case vcl::UnicodeCoverage::RESERVED5:
1639 case vcl::UnicodeCoverage::MAX_UC_ENUM:
1640 break;
1642 return eRet;
1645 OUString makeRepresentativeTextForFont(sal_Int16 nScriptType, const vcl::Font &rFont)
1647 OUString sRet(makeRepresentativeTextForLanguage(rFont.GetLanguage()));
1649 ScopedVclPtrInstance< VirtualDevice > aDevice;
1650 if (sRet.isEmpty() || (-1 != aDevice->HasGlyphs(rFont, sRet)))
1652 aDevice->SetFont(rFont);
1653 vcl::FontCapabilities aFontCapabilities;
1654 if (aDevice->GetFontCapabilities(aFontCapabilities))
1656 #if OSL_DEBUG_LEVEL > 0
1657 lcl_dump_unicode_coverage(aFontCapabilities.oUnicodeRange);
1658 #endif
1660 if (aFontCapabilities.oUnicodeRange)
1662 *aFontCapabilities.oUnicodeRange &= getWeakMask();
1664 if (nScriptType != css::i18n::ScriptType::ASIAN)
1666 *aFontCapabilities.oUnicodeRange &= getCJKMask();
1667 aFontCapabilities.oCodePageRange.reset();
1669 if (nScriptType != css::i18n::ScriptType::LATIN)
1670 *aFontCapabilities.oUnicodeRange &= getLatinMask();
1671 if (nScriptType != css::i18n::ScriptType::COMPLEX)
1672 *aFontCapabilities.oUnicodeRange &= getCTLMask();
1675 #if OSL_DEBUG_LEVEL > 0
1676 SAL_INFO("svtools", "minimal");
1677 lcl_dump_unicode_coverage(aFontCapabilities.oUnicodeRange);
1678 lcl_dump_codepage_coverage(aFontCapabilities.oCodePageRange);
1679 #endif
1681 UScriptCode eScript = getScript(aFontCapabilities);
1683 if (nScriptType == css::i18n::ScriptType::ASIAN)
1684 eScript = attemptToDisambiguateHan(eScript, *aDevice);
1686 sRet = makeRepresentativeTextForScript(eScript);
1689 if (sRet.isEmpty())
1691 if (nScriptType == css::i18n::ScriptType::COMPLEX)
1693 sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW);
1694 if (-1 != aDevice->HasGlyphs(rFont, sRet))
1696 sRet = makeMinimalTextForScript(USCRIPT_HEBREW);
1697 if (-1 != aDevice->HasGlyphs(rFont, sRet))
1698 sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC);
1701 else if (nScriptType == css::i18n::ScriptType::LATIN)
1702 sRet = makeRepresentativeTextForScript(USCRIPT_LATIN);
1706 return sRet;
1709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */