Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/metric.hxx>
14 : #include <i18nutil/unicode.hxx>
15 :
16 : // This should only be used when a commonly used font incorrectly declares its
17 : // coverage. If you add a font here, please leave a note explaining the issue
18 : // that caused it to be added
19 0 : static UScriptCode lcl_getHardCodedScriptNameForFont (const OutputDevice &rDevice)
20 : {
21 0 : const OUString &rName = rDevice.GetFont().GetName();
22 :
23 0 : if (rName == "GB18030 Bitmap")
24 : {
25 : // As of OSX 10.9, the system font "GB18030 Bitmap" incorrectly declares
26 : // that it only covers "Phoenician" when in fact it's a Chinese font.
27 0 : return USCRIPT_HAN;
28 : }
29 0 : else if (rName == "BiauKai")
30 : {
31 : // "BiauKai" makes crazy claims to cover BUGINESE, SUNDANESE, etc
32 : // but in fact it's a Traditional Chinese font.
33 0 : return USCRIPT_TRADITIONAL_HAN;
34 : }
35 0 : else if (rName == "GungSeo" || rName == "PCMyungjo" || rName == "PilGi")
36 : {
37 : // These have no OS/2 tables, but we know they are Korean fonts.
38 0 : return USCRIPT_KOREAN;
39 : }
40 0 : else if (rName == "Hei" || rName == "Kai")
41 : {
42 : // These have no OS/2 tables, but we know they are Chinese fonts.
43 0 : return USCRIPT_HAN;
44 : }
45 0 : else if (rName.startsWith("Bangla "))
46 : {
47 : // "Bangla Sangam MN" claims it supports MALAYALAM, but it doesn't
48 : // "Bangla MN" claims just DEVANAGARI and not an additional BENGALI
49 0 : return USCRIPT_BENGALI;
50 : }
51 0 : else if (rName.startsWith("Gurmukhi "))
52 : {
53 : // "Gurmukhi MN" claims it supports TAMIL, but it doesn't
54 0 : return USCRIPT_GURMUKHI;
55 : }
56 0 : else if (rName.startsWith("Kannada "))
57 : {
58 : // "Kannada MN" claims it supports TAMIL, but it doesn't
59 0 : return USCRIPT_KANNADA;
60 : }
61 0 : else if (rName.startsWith("Lao "))
62 : {
63 : // "Lao Sangam MN" claims it supports TAMIL, but it doesn't
64 0 : return USCRIPT_LAO;
65 : }
66 0 : else if (rName.startsWith("Malayalam "))
67 : {
68 : // "Malayalam MN" claims it supports TAMIL, but it doesn't
69 0 : return USCRIPT_MALAYALAM;
70 : }
71 0 : else if (rName.startsWith("Sinhala "))
72 : {
73 : // "Sinhala MN" claims it supports CYRILLIC
74 0 : return USCRIPT_SINHALA;
75 : }
76 0 : else if (rName.startsWith("Telugu "))
77 : {
78 : // "Telugu MN" claims it supports TAMIL, but it doesn't
79 0 : return USCRIPT_TELUGU;
80 : }
81 0 : else if (rName.startsWith("Myanmar "))
82 : {
83 0 : return USCRIPT_MYANMAR;
84 : }
85 0 : else if (rName == "InaiMathi")
86 : {
87 : // "InaiMathi" claims it supports GOTHIC and CJK_UNIFIED_IDEOGRAPHS as well as
88 : // TAMIL, but it doesn't
89 0 : return USCRIPT_TAMIL;
90 : }
91 0 : else if (rName == "Hannotate TC" || rName == "HanziPen TC" || rName == "Heiti TC" || rName == "Weibei TC")
92 : {
93 : // These fonts claim support for ARMENIAN and a bunch of other stuff they doesn't support
94 0 : return USCRIPT_TRADITIONAL_HAN;
95 : }
96 0 : else if (rName == "Hannotate SC" || rName == "HanziPen SC" || rName == "Heiti SC" || rName == "Weibei SC")
97 : {
98 : // These fonts claim support for ARMENIAN and a bunch of other stuff they doesn't support
99 0 : return USCRIPT_SIMPLIFIED_HAN;
100 : }
101 :
102 0 : return USCRIPT_INVALID_CODE;
103 : }
104 :
105 0 : bool isOpenSymbolFont(const vcl::Font &rFont)
106 : {
107 0 : return rFont.GetName().equalsIgnoreAsciiCase("starsymbol") ||
108 0 : rFont.GetName().equalsIgnoreAsciiCase("opensymbol");
109 : }
110 :
111 0 : bool isSymbolFont(const vcl::Font &rFont)
112 : {
113 0 : return (rFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL) ||
114 0 : rFont.GetName().equalsIgnoreAsciiCase("Apple Color Emoji") ||
115 0 : rFont.GetName().equalsIgnoreAsciiCase("cmsy10") ||
116 0 : rFont.GetName().equalsIgnoreAsciiCase("cmex10") ||
117 0 : rFont.GetName().equalsIgnoreAsciiCase("esint10") ||
118 0 : rFont.GetName().equalsIgnoreAsciiCase("feta26") ||
119 0 : rFont.GetName().equalsIgnoreAsciiCase("jsMath-cmsy10") ||
120 0 : rFont.GetName().equalsIgnoreAsciiCase("jsMath-cmex10") ||
121 0 : rFont.GetName().equalsIgnoreAsciiCase("msam10") ||
122 0 : rFont.GetName().equalsIgnoreAsciiCase("msbm10") ||
123 0 : rFont.GetName().equalsIgnoreAsciiCase("wasy10") ||
124 0 : rFont.GetName().equalsIgnoreAsciiCase("Denemo") ||
125 0 : rFont.GetName().equalsIgnoreAsciiCase("GlyphBasic1") ||
126 0 : rFont.GetName().equalsIgnoreAsciiCase("GlyphBasic2") ||
127 0 : rFont.GetName().equalsIgnoreAsciiCase("GlyphBasic3") ||
128 0 : rFont.GetName().equalsIgnoreAsciiCase("GlyphBasic4") ||
129 0 : rFont.GetName().equalsIgnoreAsciiCase("Letters Laughing") ||
130 0 : rFont.GetName().equalsIgnoreAsciiCase("MusiQwik") ||
131 0 : rFont.GetName().equalsIgnoreAsciiCase("MusiSync") ||
132 0 : rFont.GetName().equalsIgnoreAsciiCase("stmary10") ||
133 0 : rFont.GetName().equalsIgnoreAsciiCase("Symbol") ||
134 0 : rFont.GetName().startsWith("STIXIntegrals") ||
135 0 : rFont.GetName().startsWith("STIXNonUnicode") ||
136 0 : rFont.GetName().startsWith("STIXSize") ||
137 0 : rFont.GetName().startsWith("STIXVariants") ||
138 0 : isOpenSymbolFont(rFont);
139 : }
140 :
141 0 : bool canRenderNameOfSelectedFont(OutputDevice &rDevice)
142 : {
143 0 : const vcl::Font &rFont = rDevice.GetFont();
144 0 : return !isSymbolFont(rFont) && ( -1 == rDevice.HasGlyphs(rFont, rFont.GetName()) );
145 : }
146 :
147 0 : OUString makeShortRepresentativeSymbolTextForSelectedFont(OutputDevice &rDevice)
148 : {
149 0 : if (rDevice.GetFont().GetName() == "Symbol")
150 : {
151 : static const sal_Unicode aImplAppleSymbolText[] = {
152 : 0x03BC, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x03A9, 0x221A, 0};
153 0 : OUString sSampleText(aImplAppleSymbolText);
154 0 : bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText));
155 : //It's the Apple version
156 0 : if (bHasSampleTextGlyphs)
157 0 : return OUString(aImplAppleSymbolText);
158 : static const sal_Unicode aImplAdobeSymbolText[] = {
159 : 0xF06D, 0xF0B6, 0xF0E5, 0xF0D5, 0xF070, 0xF0F2, 0xF057, 0xF0D6, 0};
160 0 : return OUString(aImplAdobeSymbolText);
161 : }
162 :
163 0 : const bool bOpenSymbol = isOpenSymbolFont(rDevice.GetFont());
164 :
165 0 : if (!bOpenSymbol)
166 : {
167 0 : FontCharMapPtr pFontCharMap;
168 0 : bool bHasCharMap = rDevice.GetFontCharMap(pFontCharMap);
169 0 : if( bHasCharMap )
170 : {
171 : // use some sample characters available in the font
172 : sal_Unicode aText[8];
173 :
174 : // start just above the PUA used by most symbol fonts
175 0 : sal_uInt32 cNewChar = 0xFF00;
176 :
177 0 : const int nMaxCount = sizeof(aText)/sizeof(*aText) - 1;
178 0 : int nSkip = pFontCharMap->GetCharCount() / nMaxCount;
179 0 : if( nSkip > 10 )
180 0 : nSkip = 10;
181 0 : else if( nSkip <= 0 )
182 0 : nSkip = 1;
183 0 : for( int i = 0; i < nMaxCount; ++i )
184 : {
185 0 : sal_uInt32 cOldChar = cNewChar;
186 0 : for( int j = nSkip; --j >= 0; )
187 0 : cNewChar = pFontCharMap->GetPrevChar( cNewChar );
188 0 : if( cOldChar == cNewChar )
189 0 : break;
190 0 : aText[ i ] = static_cast<sal_Unicode>(cNewChar); // TODO: support UCS4 samples
191 0 : aText[ i+1 ] = 0;
192 : }
193 :
194 0 : return OUString(aText);
195 : }
196 :
197 0 : pFontCharMap = 0;
198 : }
199 :
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 0 : const sal_Unicode* pText = bOpenSymbol ? aImplStarSymbolText : aImplSymbolFontText;
205 0 : OUString sSampleText(pText);
206 0 : bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText));
207 0 : return bHasSampleTextGlyphs ? sSampleText : OUString();
208 : }
209 :
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"
212 :
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 0 : OUString makeShortRepresentativeTextForScript(UScriptCode eScript)
221 : {
222 0 : OUString sSampleText;
223 0 : switch (eScript)
224 : {
225 : case USCRIPT_GREEK:
226 : {
227 : const sal_Unicode aGrek[] = {
228 : 0x0391, 0x03BB, 0x03C6, 0x03AC, 0x03B2, 0x03B7, 0x03C4, 0x03BF
229 0 : };
230 0 : sSampleText = OUString(aGrek, SAL_N_ELEMENTS(aGrek));
231 0 : break;
232 : }
233 : case USCRIPT_HEBREW:
234 : {
235 : 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
239 0 : };
240 0 : sSampleText = OUString(aHebr, SAL_N_ELEMENTS(aHebr));
241 0 : break;
242 : }
243 : case USCRIPT_ARABIC:
244 : {
245 : const sal_Unicode aArab[] = {
246 : 0x0623, 0x0628, 0x062C, 0x062F, 0x064A, 0x0629, 0x0020, 0x0639,
247 : 0x0631, 0x0628, 0x064A, 0x0629
248 0 : };
249 0 : sSampleText = OUString(aArab, SAL_N_ELEMENTS(aArab));
250 0 : break;
251 : }
252 : case USCRIPT_ARMENIAN:
253 : {
254 : const sal_Unicode aArmenian[] = {
255 : 0x0561, 0x0575, 0x0562, 0x0578, 0x0582, 0x0562, 0x0565,
256 : 0x0576
257 0 : };
258 0 : sSampleText = OUString(aArmenian, SAL_N_ELEMENTS(aArmenian));
259 0 : break;
260 : }
261 : case USCRIPT_DEVANAGARI:
262 : {
263 : const sal_Unicode aDeva[] = {
264 : 0x0926, 0x0947, 0x0935, 0x0928, 0x093E, 0x0917, 0x0930, 0x0940
265 0 : };
266 0 : sSampleText = OUString(aDeva, SAL_N_ELEMENTS(aDeva));
267 0 : break;
268 : }
269 : case USCRIPT_BENGALI:
270 : {
271 : const sal_Unicode aBeng[] = {
272 : 0x09AC, 0x09BE, 0x0982, 0x09B2, 0x09BE, 0x0020, 0x09B2, 0x09BF,
273 : 0x09AA, 0x09BF
274 0 : };
275 0 : sSampleText = OUString(aBeng, SAL_N_ELEMENTS(aBeng));
276 0 : break;
277 : }
278 : case USCRIPT_GURMUKHI:
279 : {
280 : const sal_Unicode aGuru[] = {
281 : 0x0A17, 0x0A41, 0x0A30, 0x0A2E, 0x0A41, 0x0A16, 0x0A40
282 0 : };
283 0 : sSampleText = OUString(aGuru, SAL_N_ELEMENTS(aGuru));
284 0 : break;
285 : }
286 : case USCRIPT_GUJARATI:
287 : {
288 : const sal_Unicode aGujr[] = {
289 : 0x0A97, 0x0AC1, 0x0A9C, 0x0AB0, 0x0ABE, 0x0AA4, 0x0aC0, 0x0020,
290 : 0x0AB2, 0x0ABF, 0x0AAA, 0x0ABF
291 0 : };
292 0 : sSampleText = OUString(aGujr, SAL_N_ELEMENTS(aGujr));
293 0 : break;
294 : }
295 : case USCRIPT_ORIYA:
296 : {
297 : const sal_Unicode aOrya[] = {
298 : 0x0B09, 0x0B24, 0x0B4D, 0x0B15, 0x0B33, 0x0020, 0x0B32, 0x0B3F,
299 : 0x0B2A, 0x0B3F
300 0 : };
301 0 : sSampleText = OUString(aOrya, SAL_N_ELEMENTS(aOrya));
302 0 : break;
303 : }
304 : case USCRIPT_TAMIL:
305 : {
306 : const sal_Unicode aTaml[] = {
307 : 0x0B85, 0x0BB0, 0x0BBF, 0x0B9A, 0x0BCD, 0x0B9A, 0x0BC1, 0x0BB5,
308 : 0x0B9F, 0x0BBF
309 0 : };
310 0 : sSampleText = OUString(aTaml, SAL_N_ELEMENTS(aTaml));
311 0 : break;
312 : }
313 : case USCRIPT_TELUGU:
314 : {
315 : const sal_Unicode aTelu[] = {
316 : 0x0C24, 0x0C46, 0x0C32, 0x0C41, 0x0C17, 0x0C41
317 0 : };
318 0 : sSampleText = OUString(aTelu, SAL_N_ELEMENTS(aTelu));
319 0 : break;
320 : }
321 : case USCRIPT_KANNADA:
322 : {
323 : const sal_Unicode aKnda[] = {
324 : 0x0C95, 0x0CA8, 0x0CCD, 0x0CA8, 0x0CA1, 0x0020, 0x0CB2, 0x0CBF,
325 : 0x0CAA, 0x0CBF
326 0 : };
327 0 : sSampleText = OUString(aKnda, SAL_N_ELEMENTS(aKnda));
328 0 : break;
329 : }
330 : case USCRIPT_MALAYALAM:
331 : {
332 : const sal_Unicode aMlym[] = {
333 : 0x0D2E, 0x0D32, 0x0D2F, 0x0D3E, 0x0D33, 0x0D32, 0x0D3F, 0x0D2A,
334 : 0x0D3F
335 0 : };
336 0 : sSampleText = OUString(aMlym, SAL_N_ELEMENTS(aMlym));
337 0 : break;
338 : }
339 : case USCRIPT_THAI:
340 : {
341 : const sal_Unicode aThai[] = {
342 : 0x0E2D, 0x0E31, 0x0E01, 0x0E29, 0x0E23, 0x0E44, 0x0E17, 0x0E22
343 0 : };
344 0 : sSampleText = OUString(aThai, SAL_N_ELEMENTS(aThai));
345 0 : break;
346 : }
347 : case USCRIPT_LAO:
348 : {
349 : const sal_Unicode aLao[] = {
350 : 0x0EAD, 0x0EB1, 0x0E81, 0x0EAA, 0x0EAD, 0x0E99, 0x0EA5, 0x0EB2,
351 : 0x0EA7
352 0 : };
353 0 : sSampleText = OUString(aLao, SAL_N_ELEMENTS(aLao));
354 0 : break;
355 : }
356 : case USCRIPT_GEORGIAN:
357 : {
358 : const sal_Unicode aGeorgian[] = {
359 : 0x10D3, 0x10D0, 0x10DB, 0x10EC, 0x10D4, 0x10E0, 0x10DA, 0x10DD,
360 : 0x10D1, 0x10D0
361 0 : };
362 0 : sSampleText = OUString(aGeorgian, SAL_N_ELEMENTS(aGeorgian));
363 0 : break;
364 : }
365 : case USCRIPT_HANGUL:
366 : case USCRIPT_KOREAN:
367 : {
368 : const sal_Unicode aHang[] = {
369 : 0xD55C, 0xAE00
370 0 : };
371 0 : sSampleText = OUString(aHang, SAL_N_ELEMENTS(aHang));
372 0 : break;
373 : }
374 : case USCRIPT_TIBETAN:
375 : {
376 : const sal_Unicode aTibt[] = {
377 : 0x0F51, 0x0F56, 0x0F74, 0x0F0B, 0x0F45, 0x0F53, 0x0F0B
378 0 : };
379 0 : sSampleText = OUString(aTibt, SAL_N_ELEMENTS(aTibt));
380 0 : break;
381 : }
382 : case USCRIPT_SYRIAC:
383 : {
384 : const sal_Unicode aSyri[] = {
385 : 0x0723, 0x071B, 0x072A, 0x0722, 0x0713, 0x0720, 0x0710
386 0 : };
387 0 : sSampleText = OUString(aSyri, SAL_N_ELEMENTS(aSyri));
388 0 : break;
389 : }
390 : case USCRIPT_THAANA:
391 : {
392 : const sal_Unicode aThaa[] = {
393 : 0x078C, 0x07A7, 0x0782, 0x07A6
394 0 : };
395 0 : sSampleText = OUString(aThaa, SAL_N_ELEMENTS(aThaa));
396 0 : break;
397 : }
398 : case USCRIPT_SINHALA:
399 : {
400 : const sal_Unicode aSinh[] = {
401 : 0x0DC1, 0x0DD4, 0x0DAF, 0x0DCA, 0x0DB0, 0x0020, 0x0DC3, 0x0DD2,
402 : 0x0D82, 0x0DC4, 0x0DBD
403 0 : };
404 0 : sSampleText = OUString(aSinh, SAL_N_ELEMENTS(aSinh));
405 0 : break;
406 : }
407 : case USCRIPT_MYANMAR:
408 : {
409 : const sal_Unicode aMymr[] = {
410 : 0x1019, 0x103C, 0x1014, 0x103A, 0x1019, 0x102C, 0x1021, 0x1000,
411 : 0x1039, 0x1001, 0x101B, 0x102C
412 0 : };
413 0 : sSampleText = OUString(aMymr, SAL_N_ELEMENTS(aMymr));
414 0 : break;
415 : }
416 : case USCRIPT_ETHIOPIC:
417 : {
418 : const sal_Unicode aEthi[] = {
419 : 0x130D, 0x12D5, 0x12DD
420 0 : };
421 0 : sSampleText = OUString(aEthi, SAL_N_ELEMENTS(aEthi));
422 0 : break;
423 : }
424 : case USCRIPT_CHEROKEE:
425 : {
426 : const sal_Unicode aCher[] = {
427 : 0x13D7, 0x13AA, 0x13EA, 0x13B6, 0x13D9, 0x13D7
428 0 : };
429 0 : sSampleText = OUString(aCher, SAL_N_ELEMENTS(aCher));
430 0 : break;
431 : }
432 : case USCRIPT_KHMER:
433 : {
434 : const sal_Unicode aKhmr[] = {
435 : 0x17A2, 0x1780, 0x17D2, 0x1781, 0x179A, 0x1780, 0x17D2, 0x179A,
436 : 0x1798, 0x1781, 0x17C1, 0x1798, 0x179A, 0x1797, 0x17B6, 0x179F,
437 : 0x17B6
438 0 : };
439 0 : sSampleText = OUString(aKhmr, SAL_N_ELEMENTS(aKhmr));
440 0 : break;
441 : }
442 : case USCRIPT_MONGOLIAN:
443 : {
444 : const sal_Unicode aMongolian[] = {
445 : 0x182A, 0x1822, 0x1834, 0x1822, 0x182D, 0x180C
446 0 : };
447 0 : sSampleText = OUString(aMongolian, SAL_N_ELEMENTS(aMongolian));
448 0 : break;
449 : }
450 : case USCRIPT_TAGALOG:
451 : {
452 : const sal_Unicode aTagalog[] = {
453 : 0x170A, 0x170A, 0x170C, 0x1712
454 0 : };
455 0 : sSampleText = OUString(aTagalog, SAL_N_ELEMENTS(aTagalog));
456 0 : break;
457 : }
458 : case USCRIPT_NEW_TAI_LUE:
459 : {
460 : const sal_Unicode aTalu[] = {
461 : 0x1991, 0x19BA, 0x199F, 0x19B9, 0x19C9
462 0 : };
463 0 : sSampleText = OUString(aTalu, SAL_N_ELEMENTS(aTalu));
464 0 : break;
465 : }
466 : case USCRIPT_TRADITIONAL_HAN:
467 : {
468 : const sal_Unicode aHant[] = {
469 : 0x7E41
470 0 : };
471 0 : sSampleText = OUString(aHant, SAL_N_ELEMENTS(aHant));
472 0 : break;
473 : }
474 : case USCRIPT_SIMPLIFIED_HAN:
475 : {
476 : const sal_Unicode aHans[] = {
477 : 0x7B80
478 0 : };
479 0 : sSampleText = OUString(aHans, SAL_N_ELEMENTS(aHans));
480 0 : break;
481 : }
482 : case USCRIPT_HAN:
483 : {
484 : const sal_Unicode aSimplifiedAndTraditionalChinese[] = {
485 : 0x7B80, 0x7E41
486 0 : };
487 0 : sSampleText = OUString(aSimplifiedAndTraditionalChinese,
488 0 : SAL_N_ELEMENTS(aSimplifiedAndTraditionalChinese));
489 0 : break;
490 : }
491 : case USCRIPT_JAPANESE:
492 : {
493 : const sal_Unicode aJpan[] = {
494 : 0x65E5, 0x672C, 0x8A9E
495 0 : };
496 0 : sSampleText = OUString(aJpan, SAL_N_ELEMENTS(aJpan));
497 0 : break;
498 : }
499 : case USCRIPT_YI:
500 : {
501 : const sal_Unicode aYiii[] = {
502 : 0xA188, 0xA320, 0xA071, 0xA0B7
503 0 : };
504 0 : sSampleText = OUString(aYiii, SAL_N_ELEMENTS(aYiii));
505 0 : break;
506 : }
507 : case USCRIPT_PHAGS_PA:
508 : {
509 : const sal_Unicode aPhag[] = {
510 : 0xA84F, 0xA861, 0xA843, 0x0020, 0xA863, 0xA861, 0xA859, 0x0020,
511 : 0xA850, 0xA85C, 0xA85E
512 0 : };
513 0 : sSampleText = OUString(aPhag, SAL_N_ELEMENTS(aPhag));
514 0 : break;
515 : }
516 : case USCRIPT_TAI_LE:
517 : {
518 : const sal_Unicode aTale[] = {
519 : 0x1956, 0x196D, 0x1970, 0x1956, 0x196C, 0x1973, 0x1951, 0x1968,
520 : 0x1952, 0x1970
521 0 : };
522 0 : sSampleText = OUString(aTale, SAL_N_ELEMENTS(aTale));
523 0 : break;
524 : }
525 : case USCRIPT_LATIN:
526 0 : sSampleText = "Lorem ipsum";
527 0 : break;
528 : default:
529 0 : break;
530 : }
531 0 : return sSampleText;
532 : }
533 :
534 0 : OUString makeRepresentativeTextForScript(UScriptCode eScript)
535 : {
536 0 : OUString sSampleText;
537 0 : switch (eScript)
538 : {
539 : case USCRIPT_TRADITIONAL_HAN:
540 : case USCRIPT_SIMPLIFIED_HAN:
541 : case USCRIPT_HAN:
542 : {
543 : //Three Character Classic
544 : const sal_Unicode aZh[] = {
545 : 0x4EBA, 0x4E4B, 0x521D, 0x0020, 0x6027, 0x672C, 0x5584
546 0 : };
547 0 : sSampleText = OUString(aZh, SAL_N_ELEMENTS(aZh));
548 0 : break;
549 : }
550 : case USCRIPT_JAPANESE:
551 : {
552 : //'Beautiful Japanese'
553 : const sal_Unicode aJa[] = {
554 : 0x7F8E, 0x3057, 0x3044, 0x65E5, 0x672C, 0x8A9E
555 0 : };
556 0 : sSampleText = OUString(aJa, SAL_N_ELEMENTS(aJa));
557 0 : break;
558 : }
559 : case USCRIPT_KOREAN:
560 : case USCRIPT_HANGUL:
561 : {
562 : //The essential condition for...
563 : const sal_Unicode aKo[] = {
564 : 0xD0A4, 0xC2A4, 0xC758, 0x0020, 0xACE0, 0xC720, 0xC870,
565 : 0xAC74, 0xC740
566 0 : };
567 0 : sSampleText = OUString(aKo, SAL_N_ELEMENTS(aKo));
568 0 : break;
569 : }
570 : default:
571 0 : break;
572 : }
573 :
574 0 : if (sSampleText.isEmpty())
575 0 : sSampleText = makeShortRepresentativeTextForScript(eScript);
576 0 : return sSampleText;
577 : }
578 :
579 0 : OUString makeShortMinimalTextForScript(UScriptCode eScript)
580 : {
581 0 : OUString sSampleText;
582 0 : switch (eScript)
583 : {
584 : case USCRIPT_GREEK:
585 : {
586 : const sal_Unicode aGrek[] = {
587 : 0x0391, 0x0392
588 0 : };
589 0 : sSampleText = OUString(aGrek, SAL_N_ELEMENTS(aGrek));
590 0 : break;
591 : }
592 : case USCRIPT_HEBREW:
593 : {
594 : const sal_Unicode aHebr[] = {
595 : 0x05D0, 0x05D1
596 0 : };
597 0 : sSampleText = OUString(aHebr, SAL_N_ELEMENTS(aHebr));
598 0 : break;
599 : }
600 : default:
601 0 : break;
602 : }
603 0 : return sSampleText;
604 : }
605 :
606 0 : OUString makeMinimalTextForScript(UScriptCode eScript)
607 : {
608 0 : return makeShortMinimalTextForScript(eScript);
609 : }
610 :
611 : //These ones are typically for use in the font preview window in format
612 : //character
613 :
614 : //There we generally know the language. Though its possible for the language to
615 : //be "none".
616 :
617 : //Currently we fall back to makeShortRepresentativeTextForScript when we don't
618 : //have suitable strings
619 0 : OUString makeRepresentativeTextForLanguage(LanguageType eLang)
620 : {
621 0 : OUString sRet;
622 0 : switch( eLang & LANGUAGE_MASK_PRIMARY )
623 : {
624 : case LANGUAGE_ARMENIAN & LANGUAGE_MASK_PRIMARY:
625 0 : sRet = makeRepresentativeTextForScript(USCRIPT_ARMENIAN);
626 0 : break;
627 : case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY:
628 0 : sRet = makeRepresentativeTextForScript(USCRIPT_HAN);
629 0 : break;
630 : case LANGUAGE_GREEK & LANGUAGE_MASK_PRIMARY:
631 0 : sRet = makeRepresentativeTextForScript(USCRIPT_GREEK);
632 0 : break;
633 : case LANGUAGE_HEBREW & LANGUAGE_MASK_PRIMARY:
634 : case LANGUAGE_YIDDISH & LANGUAGE_MASK_PRIMARY:
635 0 : sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW);
636 0 : break;
637 : case LANGUAGE_ARABIC_SAUDI_ARABIA & LANGUAGE_MASK_PRIMARY:
638 0 : sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC);
639 0 : break;
640 : case LANGUAGE_HINDI & LANGUAGE_MASK_PRIMARY:
641 0 : sRet = makeRepresentativeTextForScript(USCRIPT_DEVANAGARI);
642 0 : break;
643 : case LANGUAGE_ASSAMESE & LANGUAGE_MASK_PRIMARY:
644 : {
645 : const sal_Unicode aAs[] = {
646 : 0x0985, 0x09B8, 0x09AE, 0x09C0, 0x09AF, 0x09BC, 0x09BE,
647 : 0x0020, 0x0986, 0x0996, 0x09F0
648 0 : };
649 0 : sRet = OUString(aAs, SAL_N_ELEMENTS(aAs));
650 0 : break;
651 : }
652 : case LANGUAGE_BENGALI & LANGUAGE_MASK_PRIMARY:
653 0 : sRet = makeRepresentativeTextForScript(USCRIPT_BENGALI);
654 0 : break;
655 : case LANGUAGE_PUNJABI & LANGUAGE_MASK_PRIMARY:
656 0 : sRet = makeRepresentativeTextForScript(USCRIPT_GURMUKHI);
657 0 : break;
658 : case LANGUAGE_GUJARATI & LANGUAGE_MASK_PRIMARY:
659 0 : sRet = makeRepresentativeTextForScript(USCRIPT_GUJARATI);
660 0 : break;
661 : case LANGUAGE_ODIA & LANGUAGE_MASK_PRIMARY:
662 0 : sRet = makeRepresentativeTextForScript(USCRIPT_ORIYA);
663 0 : break;
664 : case LANGUAGE_TAMIL & LANGUAGE_MASK_PRIMARY:
665 0 : sRet = makeRepresentativeTextForScript(USCRIPT_TAMIL);
666 0 : break;
667 : case LANGUAGE_TELUGU & LANGUAGE_MASK_PRIMARY:
668 0 : sRet = makeRepresentativeTextForScript(USCRIPT_TELUGU);
669 0 : break;
670 : case LANGUAGE_KANNADA & LANGUAGE_MASK_PRIMARY:
671 0 : sRet = makeRepresentativeTextForScript(USCRIPT_KANNADA);
672 0 : break;
673 : case LANGUAGE_MALAYALAM & LANGUAGE_MASK_PRIMARY:
674 0 : sRet = makeRepresentativeTextForScript(USCRIPT_MALAYALAM);
675 0 : break;
676 : case LANGUAGE_THAI & LANGUAGE_MASK_PRIMARY:
677 0 : sRet = makeRepresentativeTextForScript(USCRIPT_THAI);
678 0 : break;
679 : case LANGUAGE_LAO & LANGUAGE_MASK_PRIMARY:
680 0 : sRet = makeRepresentativeTextForScript(USCRIPT_LAO);
681 0 : break;
682 : case LANGUAGE_GEORGIAN & LANGUAGE_MASK_PRIMARY:
683 0 : sRet = makeRepresentativeTextForScript(USCRIPT_GEORGIAN);
684 0 : break;
685 : case LANGUAGE_KOREAN & LANGUAGE_MASK_PRIMARY:
686 0 : sRet = makeRepresentativeTextForScript(USCRIPT_KOREAN);
687 0 : break;
688 : case LANGUAGE_TIBETAN & LANGUAGE_MASK_PRIMARY:
689 0 : sRet = makeRepresentativeTextForScript(USCRIPT_TIBETAN);
690 0 : break;
691 : case LANGUAGE_SYRIAC & LANGUAGE_MASK_PRIMARY:
692 0 : sRet = makeRepresentativeTextForScript(USCRIPT_SYRIAC);
693 0 : break;
694 : case LANGUAGE_SINHALESE_SRI_LANKA & LANGUAGE_MASK_PRIMARY:
695 0 : sRet = makeRepresentativeTextForScript(USCRIPT_SINHALA);
696 0 : break;
697 : case LANGUAGE_BURMESE & LANGUAGE_MASK_PRIMARY:
698 0 : sRet = makeRepresentativeTextForScript(USCRIPT_MYANMAR);
699 0 : break;
700 : case LANGUAGE_AMHARIC_ETHIOPIA & LANGUAGE_MASK_PRIMARY:
701 0 : sRet = makeRepresentativeTextForScript(USCRIPT_ETHIOPIC);
702 0 : break;
703 : case LANGUAGE_CHEROKEE_UNITED_STATES & LANGUAGE_MASK_PRIMARY:
704 0 : sRet = makeRepresentativeTextForScript(USCRIPT_CHEROKEE);
705 0 : break;
706 : case LANGUAGE_KHMER & LANGUAGE_MASK_PRIMARY:
707 0 : sRet = makeRepresentativeTextForScript(USCRIPT_KHMER);
708 0 : break;
709 : case LANGUAGE_MONGOLIAN_MONGOLIAN_LSO & LANGUAGE_MASK_PRIMARY:
710 0 : switch (eLang)
711 : {
712 : case LANGUAGE_MONGOLIAN_MONGOLIAN_MONGOLIA:
713 : case LANGUAGE_MONGOLIAN_MONGOLIAN_CHINA:
714 : case LANGUAGE_MONGOLIAN_MONGOLIAN_LSO:
715 0 : sRet = makeRepresentativeTextForScript(USCRIPT_MONGOLIAN);
716 0 : break;
717 : default:
718 0 : break;
719 : }
720 0 : break;
721 : case LANGUAGE_JAPANESE & LANGUAGE_MASK_PRIMARY:
722 0 : sRet = makeRepresentativeTextForScript(USCRIPT_JAPANESE);
723 0 : break;
724 : case LANGUAGE_YI & LANGUAGE_MASK_PRIMARY:
725 0 : sRet = makeRepresentativeTextForScript(USCRIPT_YI);
726 0 : break;
727 : case LANGUAGE_GAELIC_IRELAND & LANGUAGE_MASK_PRIMARY:
728 : {
729 : const sal_Unicode aGa[] = {
730 : 'T', 0x00E9, 'a', 'c', 's', ' ', 'S', 'a', 'm', 'p', 'l', 'a', 'c', 'h'
731 0 : };
732 0 : sRet = OUString(aGa, SAL_N_ELEMENTS(aGa));
733 0 : break;
734 : }
735 : default:
736 0 : break;
737 : }
738 :
739 0 : return sRet;
740 : }
741 :
742 : namespace
743 : {
744 : #if OSL_DEBUG_LEVEL > 2
745 : void lcl_dump_unicode_coverage(const boost::dynamic_bitset<sal_uInt32> &rIn)
746 : {
747 : if (rIn.none())
748 : {
749 : fprintf(stderr, "<NONE>\n");
750 : return;
751 : }
752 : if (rIn[vcl::UnicodeCoverage::BASIC_LATIN])
753 : fprintf(stderr, "BASIC_LATIN\n");
754 : if (rIn[vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT])
755 : fprintf(stderr, "LATIN_1_SUPPLEMENT\n");
756 : if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_A])
757 : fprintf(stderr, "LATIN_EXTENDED_A\n");
758 : if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_B])
759 : fprintf(stderr, "LATIN_EXTENDED_B\n");
760 : if (rIn[vcl::UnicodeCoverage::IPA_EXTENSIONS])
761 : fprintf(stderr, "IPA_EXTENSIONS\n");
762 : if (rIn[vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS])
763 : fprintf(stderr, "SPACING_MODIFIER_LETTERS\n");
764 : if (rIn[vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS])
765 : fprintf(stderr, "COMBINING_DIACRITICAL_MARKS\n");
766 : if (rIn[vcl::UnicodeCoverage::GREEK_AND_COPTIC])
767 : fprintf(stderr, "GREEK_AND_COPTIC\n");
768 : if (rIn[vcl::UnicodeCoverage::COPTIC])
769 : fprintf(stderr, "COPTIC\n");
770 : if (rIn[vcl::UnicodeCoverage::CYRILLIC])
771 : fprintf(stderr, "CYRILLIC\n");
772 : if (rIn[vcl::UnicodeCoverage::ARMENIAN])
773 : fprintf(stderr, "ARMENIAN\n");
774 : if (rIn[vcl::UnicodeCoverage::HEBREW])
775 : fprintf(stderr, "HEBREW\n");
776 : if (rIn[vcl::UnicodeCoverage::VAI])
777 : fprintf(stderr, "VAI\n");
778 : if (rIn[vcl::UnicodeCoverage::ARABIC])
779 : fprintf(stderr, "ARABIC\n");
780 : if (rIn[vcl::UnicodeCoverage::NKO])
781 : fprintf(stderr, "NKO\n");
782 : if (rIn[vcl::UnicodeCoverage::DEVANAGARI])
783 : fprintf(stderr, "DEVANAGARI\n");
784 : if (rIn[vcl::UnicodeCoverage::BENGALI])
785 : fprintf(stderr, "BENGALI\n");
786 : if (rIn[vcl::UnicodeCoverage::GURMUKHI])
787 : fprintf(stderr, "GURMUKHI\n");
788 : if (rIn[vcl::UnicodeCoverage::GUJARATI])
789 : fprintf(stderr, "GUJARATI\n");
790 : if (rIn[vcl::UnicodeCoverage::ODIA])
791 : fprintf(stderr, "ODIA\n");
792 : if (rIn[vcl::UnicodeCoverage::TAMIL])
793 : fprintf(stderr, "TAMIL\n");
794 : if (rIn[vcl::UnicodeCoverage::TELUGU])
795 : fprintf(stderr, "TELUGU\n");
796 : if (rIn[vcl::UnicodeCoverage::KANNADA])
797 : fprintf(stderr, "KANNADA\n");
798 : if (rIn[vcl::UnicodeCoverage::MALAYALAM])
799 : fprintf(stderr, "MALAYALAM\n");
800 : if (rIn[vcl::UnicodeCoverage::THAI])
801 : fprintf(stderr, "THAI\n");
802 : if (rIn[vcl::UnicodeCoverage::LAO])
803 : fprintf(stderr, "LAO\n");
804 : if (rIn[vcl::UnicodeCoverage::GEORGIAN])
805 : fprintf(stderr, "GEORGIAN\n");
806 : if (rIn[vcl::UnicodeCoverage::BALINESE])
807 : fprintf(stderr, "BALINESE\n");
808 : if (rIn[vcl::UnicodeCoverage::HANGUL_JAMO])
809 : fprintf(stderr, "HANGUL_JAMO\n");
810 : if (rIn[vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL])
811 : fprintf(stderr, "LATIN_EXTENDED_ADDITIONAL\n");
812 : if (rIn[vcl::UnicodeCoverage::GREEK_EXTENDED])
813 : fprintf(stderr, "GREEK_EXTENDED\n");
814 : if (rIn[vcl::UnicodeCoverage::GENERAL_PUNCTUATION])
815 : fprintf(stderr, "GENERAL_PUNCTUATION\n");
816 : if (rIn[vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS])
817 : fprintf(stderr, "SUPERSCRIPTS_AND_SUBSCRIPTS\n");
818 : if (rIn[vcl::UnicodeCoverage::CURRENCY_SYMBOLS])
819 : fprintf(stderr, "CURRENCY_SYMBOLS\n");
820 : if (rIn[vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS])
821 : fprintf(stderr, "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS\n");
822 : if (rIn[vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS])
823 : fprintf(stderr, "LETTERLIKE_SYMBOLS\n");
824 : if (rIn[vcl::UnicodeCoverage::NUMBER_FORMS])
825 : fprintf(stderr, "NUMBER_FORMS\n");
826 : if (rIn[vcl::UnicodeCoverage::ARROWS])
827 : fprintf(stderr, "ARROWS\n");
828 : if (rIn[vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS])
829 : fprintf(stderr, "MATHEMATICAL_OPERATORS\n");
830 : if (rIn[vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL])
831 : fprintf(stderr, "MISCELLANEOUS_TECHNICAL\n");
832 : if (rIn[vcl::UnicodeCoverage::CONTROL_PICTURES])
833 : fprintf(stderr, "CONTROL_PICTURES\n");
834 : if (rIn[vcl::UnicodeCoverage::OPTICAL_CHARACTER_RECOGNITION])
835 : fprintf(stderr, "OPTICAL_CHARACTER_RECOGNITION\n");
836 : if (rIn[vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS])
837 : fprintf(stderr, "ENCLOSED_ALPHANUMERICS\n");
838 : if (rIn[vcl::UnicodeCoverage::BOX_DRAWING])
839 : fprintf(stderr, "BOX_DRAWING\n");
840 : if (rIn[vcl::UnicodeCoverage::BLOCK_ELEMENTS])
841 : fprintf(stderr, "BLOCK_ELEMENTS\n");
842 : if (rIn[vcl::UnicodeCoverage::GEOMETRIC_SHAPES])
843 : fprintf(stderr, "GEOMETRIC_SHAPES\n");
844 : if (rIn[vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS])
845 : fprintf(stderr, "MISCELLANEOUS_SYMBOLS\n");
846 : if (rIn[vcl::UnicodeCoverage::DINGBATS])
847 : fprintf(stderr, "DINGBATS\n");
848 : if (rIn[vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION])
849 : fprintf(stderr, "CJK_SYMBOLS_AND_PUNCTUATION\n");
850 : if (rIn[vcl::UnicodeCoverage::HIRAGANA])
851 : fprintf(stderr, "HIRAGANA\n");
852 : if (rIn[vcl::UnicodeCoverage::KATAKANA])
853 : fprintf(stderr, "KATAKANA\n");
854 : if (rIn[vcl::UnicodeCoverage::BOPOMOFO])
855 : fprintf(stderr, "BOPOMOFO\n");
856 : if (rIn[vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO])
857 : fprintf(stderr, "HANGUL_COMPATIBILITY_JAMO\n");
858 : if (rIn[vcl::UnicodeCoverage::PHAGS_PA])
859 : fprintf(stderr, "PHAGS_PA\n");
860 : if (rIn[vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS])
861 : fprintf(stderr, "ENCLOSED_CJK_LETTERS_AND_MONTHS\n");
862 : if (rIn[vcl::UnicodeCoverage::CJK_COMPATIBILITY])
863 : fprintf(stderr, "CJK_COMPATIBILITY\n");
864 : if (rIn[vcl::UnicodeCoverage::HANGUL_SYLLABLES])
865 : fprintf(stderr, "HANGUL_SYLLABLES\n");
866 : if (rIn[vcl::UnicodeCoverage::NONPLANE_0])
867 : fprintf(stderr, "NONPLANE_0\n");
868 : if (rIn[vcl::UnicodeCoverage::PHOENICIAN])
869 : fprintf(stderr, "PHOENICIAN\n");
870 : if (rIn[vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS])
871 : fprintf(stderr, "CJK_UNIFIED_IDEOGRAPHS\n");
872 : if (rIn[vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0])
873 : fprintf(stderr, "PRIVATE_USE_AREA_PLANE_0\n");
874 : if (rIn[vcl::UnicodeCoverage::CJK_STROKES])
875 : fprintf(stderr, "CJK_STROKES\n");
876 : if (rIn[vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS])
877 : fprintf(stderr, "ALPHABETIC_PRESENTATION_FORMS\n");
878 : if (rIn[vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A])
879 : fprintf(stderr, "ARABIC_PRESENTATION_FORMS_A\n");
880 : if (rIn[vcl::UnicodeCoverage::COMBINING_HALF_MARKS])
881 : fprintf(stderr, "COMBINING_HALF_MARKS\n");
882 : if (rIn[vcl::UnicodeCoverage::VERTICAL_FORMS])
883 : fprintf(stderr, "VERTICAL_FORMS\n");
884 : if (rIn[vcl::UnicodeCoverage::SMALL_FORM_VARIANTS])
885 : fprintf(stderr, "SMALL_FORM_VARIANTS\n");
886 : if (rIn[vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B])
887 : fprintf(stderr, "ARABIC_PRESENTATION_FORMS_B\n");
888 : if (rIn[vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS])
889 : fprintf(stderr, "HALFWIDTH_AND_FULLWIDTH_FORMS\n");
890 : if (rIn[vcl::UnicodeCoverage::SPECIALS])
891 : fprintf(stderr, "SPECIALS\n");
892 : if (rIn[vcl::UnicodeCoverage::TIBETAN])
893 : fprintf(stderr, "TIBETAN\n");
894 : if (rIn[vcl::UnicodeCoverage::SYRIAC])
895 : fprintf(stderr, "SYRIAC\n");
896 : if (rIn[vcl::UnicodeCoverage::THAANA])
897 : fprintf(stderr, "THAANA\n");
898 : if (rIn[vcl::UnicodeCoverage::SINHALA])
899 : fprintf(stderr, "SINHALA\n");
900 : if (rIn[vcl::UnicodeCoverage::MYANMAR])
901 : fprintf(stderr, "MYANMAR\n");
902 : if (rIn[vcl::UnicodeCoverage::ETHIOPIC])
903 : fprintf(stderr, "ETHIOPIC\n");
904 : if (rIn[vcl::UnicodeCoverage::CHEROKEE])
905 : fprintf(stderr, "CHEROKEE\n");
906 : if (rIn[vcl::UnicodeCoverage::UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS])
907 : fprintf(stderr, "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS\n");
908 : if (rIn[vcl::UnicodeCoverage::OGHAM])
909 : fprintf(stderr, "OGHAM\n");
910 : if (rIn[vcl::UnicodeCoverage::RUNIC])
911 : fprintf(stderr, "RUNIC\n");
912 : if (rIn[vcl::UnicodeCoverage::KHMER])
913 : fprintf(stderr, "KHMER\n");
914 : if (rIn[vcl::UnicodeCoverage::MONGOLIAN])
915 : fprintf(stderr, "MONGOLIAN\n");
916 : if (rIn[vcl::UnicodeCoverage::BRAILLE_PATTERNS])
917 : fprintf(stderr, "BRAILLE_PATTERNS\n");
918 : if (rIn[vcl::UnicodeCoverage::YI_SYLLABLES])
919 : fprintf(stderr, "YI_SYLLABLES\n");
920 : if (rIn[vcl::UnicodeCoverage::TAGALOG])
921 : fprintf(stderr, "TAGALOG\n");
922 : if (rIn[vcl::UnicodeCoverage::OLD_ITALIC])
923 : fprintf(stderr, "OLD_ITALIC\n");
924 : if (rIn[vcl::UnicodeCoverage::GOTHIC])
925 : fprintf(stderr, "GOTHIC\n");
926 : if (rIn[vcl::UnicodeCoverage::DESERET])
927 : fprintf(stderr, "DESERET\n");
928 : if (rIn[vcl::UnicodeCoverage::BYZANTINE_MUSICAL_SYMBOLS])
929 : fprintf(stderr, "BYZANTINE_MUSICAL_SYMBOLS\n");
930 : if (rIn[vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS])
931 : fprintf(stderr, "MATHEMATICAL_ALPHANUMERIC_SYMBOLS\n");
932 : if (rIn[vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15])
933 : fprintf(stderr, "PRIVATE_USE_PLANE_15\n");
934 : if (rIn[vcl::UnicodeCoverage::VARIATION_SELECTORS])
935 : fprintf(stderr, "VARIATION_SELECTORS\n");
936 : if (rIn[vcl::UnicodeCoverage::TAGS])
937 : fprintf(stderr, "TAGS\n");
938 : if (rIn[vcl::UnicodeCoverage::LIMBU])
939 : fprintf(stderr, "LIMBU\n");
940 : if (rIn[vcl::UnicodeCoverage::TAI_LE])
941 : fprintf(stderr, "TAI_LE\n");
942 : if (rIn[vcl::UnicodeCoverage::NEW_TAI_LUE])
943 : fprintf(stderr, "NEW_TAI_LUE\n");
944 : if (rIn[vcl::UnicodeCoverage::BUGINESE])
945 : fprintf(stderr, "BUGINESE\n");
946 : if (rIn[vcl::UnicodeCoverage::GLAGOLITIC])
947 : fprintf(stderr, "GLAGOLITIC\n");
948 : if (rIn[vcl::UnicodeCoverage::TIFINAGH])
949 : fprintf(stderr, "TIFINAGH\n");
950 : if (rIn[vcl::UnicodeCoverage::YIJING_HEXAGRAM_SYMBOLS])
951 : fprintf(stderr, "YIJING_HEXAGRAM_SYMBOLS\n");
952 : if (rIn[vcl::UnicodeCoverage::SYLOTI_NAGRI])
953 : fprintf(stderr, "SYLOTI_NAGRI\n");
954 : if (rIn[vcl::UnicodeCoverage::LINEAR_B_SYLLABARY])
955 : fprintf(stderr, "LINEAR_B_SYLLABARY\n");
956 : if (rIn[vcl::UnicodeCoverage::ANCIENT_GREEK_NUMBERS])
957 : fprintf(stderr, "ANCIENT_GREEK_NUMBERS\n");
958 : if (rIn[vcl::UnicodeCoverage::UGARITIC])
959 : fprintf(stderr, "UGARITIC\n");
960 : if (rIn[vcl::UnicodeCoverage::OLD_PERSIAN])
961 : fprintf(stderr, "OLD_PERSIAN\n");
962 : if (rIn[vcl::UnicodeCoverage::SHAVIAN])
963 : fprintf(stderr, "SHAVIAN\n");
964 : if (rIn[vcl::UnicodeCoverage::OSMANYA])
965 : fprintf(stderr, "OSMANYA\n");
966 : if (rIn[vcl::UnicodeCoverage::CYPRIOT_SYLLABARY])
967 : fprintf(stderr, "CYPRIOT_SYLLABARY\n");
968 : if (rIn[vcl::UnicodeCoverage::KHAROSHTHI])
969 : fprintf(stderr, "KHAROSHTHI\n");
970 : if (rIn[vcl::UnicodeCoverage::TAI_XUAN_JING_SYMBOLS])
971 : fprintf(stderr, "TAI_XUAN_JING_SYMBOLS\n");
972 : if (rIn[vcl::UnicodeCoverage::CUNEIFORM])
973 : fprintf(stderr, "CUNEIFORM\n");
974 : if (rIn[vcl::UnicodeCoverage::COUNTING_ROD_NUMERALS])
975 : fprintf(stderr, "COUNTING_ROD_NUMERALS\n");
976 : if (rIn[vcl::UnicodeCoverage::SUNDANESE])
977 : fprintf(stderr, "SUNDANESE\n");
978 : if (rIn[vcl::UnicodeCoverage::LEPCHA])
979 : fprintf(stderr, "LEPCHA\n");
980 : if (rIn[vcl::UnicodeCoverage::OL_CHIKI])
981 : fprintf(stderr, "OL_CHIKI\n");
982 : if (rIn[vcl::UnicodeCoverage::SAURASHTRA])
983 : fprintf(stderr, "SAURASHTRA\n");
984 : if (rIn[vcl::UnicodeCoverage::KAYAH_LI])
985 : fprintf(stderr, "KAYAH_LI\n");
986 : if (rIn[vcl::UnicodeCoverage::REJANG])
987 : fprintf(stderr, "REJANG\n");
988 : if (rIn[vcl::UnicodeCoverage::CHAM])
989 : fprintf(stderr, "CHAM\n");
990 : if (rIn[vcl::UnicodeCoverage::ANCIENT_SYMBOLS])
991 : fprintf(stderr, "ANCIENT_SYMBOLS\n");
992 : if (rIn[vcl::UnicodeCoverage::PHAISTOS_DISC])
993 : fprintf(stderr, "PHAISTOS_DISC\n");
994 : if (rIn[vcl::UnicodeCoverage::CARIAN])
995 : fprintf(stderr, "CARIAN\n");
996 : if (rIn[vcl::UnicodeCoverage::DOMINO_TILES])
997 : fprintf(stderr, "DOMINO_TILES\n");
998 : if (rIn[vcl::UnicodeCoverage::RESERVED1])
999 : fprintf(stderr, "RESERVED1\n");
1000 : if (rIn[vcl::UnicodeCoverage::RESERVED2])
1001 : fprintf(stderr, "RESERVED2\n");
1002 : if (rIn[vcl::UnicodeCoverage::RESERVED3])
1003 : fprintf(stderr, "RESERVED3\n");
1004 : if (rIn[vcl::UnicodeCoverage::RESERVED4])
1005 : fprintf(stderr, "RESERVED4\n");
1006 : if (rIn[vcl::UnicodeCoverage::RESERVED5])
1007 : fprintf(stderr, "RESERVED5\n");
1008 : }
1009 :
1010 : void lcl_dump_codepage_coverage(const boost::dynamic_bitset<sal_uInt32> &rIn)
1011 : {
1012 : if (rIn.none())
1013 : {
1014 : fprintf(stderr, "<NONE>\n");
1015 : return;
1016 : }
1017 : if (rIn[vcl::CodePageCoverage::CP1252])
1018 : fprintf(stderr, "CP1252\n");
1019 : if (rIn[vcl::CodePageCoverage::CP1250])
1020 : fprintf(stderr, "CP1250\n");
1021 : if (rIn[vcl::CodePageCoverage::CP1251])
1022 : fprintf(stderr, "CP1251\n");
1023 : if (rIn[vcl::CodePageCoverage::CP1253])
1024 : fprintf(stderr, "CP1253\n");
1025 : if (rIn[vcl::CodePageCoverage::CP1254])
1026 : fprintf(stderr, "CP1254\n");
1027 : if (rIn[vcl::CodePageCoverage::CP1255])
1028 : fprintf(stderr, "CP1255\n");
1029 : if (rIn[vcl::CodePageCoverage::CP1256])
1030 : fprintf(stderr, "CP1256\n");
1031 : if (rIn[vcl::CodePageCoverage::CP1257])
1032 : fprintf(stderr, "CP1257\n");
1033 : if (rIn[vcl::CodePageCoverage::CP1258])
1034 : fprintf(stderr, "CP1258\n");
1035 : if (rIn[vcl::CodePageCoverage::CP874])
1036 : fprintf(stderr, "CP874\n");
1037 : if (rIn[vcl::CodePageCoverage::CP932])
1038 : fprintf(stderr, "CP932\n");
1039 : if (rIn[vcl::CodePageCoverage::CP936])
1040 : fprintf(stderr, "CP936\n");
1041 : if (rIn[vcl::CodePageCoverage::CP949])
1042 : fprintf(stderr, "CP949\n");
1043 : if (rIn[vcl::CodePageCoverage::CP950])
1044 : fprintf(stderr, "CP950\n");
1045 : if (rIn[vcl::CodePageCoverage::CP1361])
1046 : fprintf(stderr, "CP1361\n");
1047 : if (rIn[vcl::CodePageCoverage::CP869])
1048 : fprintf(stderr, "CP869\n");
1049 : if (rIn[vcl::CodePageCoverage::CP866])
1050 : fprintf(stderr, "CP866\n");
1051 : if (rIn[vcl::CodePageCoverage::CP865])
1052 : fprintf(stderr, "CP865\n");
1053 : if (rIn[vcl::CodePageCoverage::CP864])
1054 : fprintf(stderr, "CP864\n");
1055 : if (rIn[vcl::CodePageCoverage::CP863])
1056 : fprintf(stderr, "CP863\n");
1057 : if (rIn[vcl::CodePageCoverage::CP862])
1058 : fprintf(stderr, "CP862\n");
1059 : if (rIn[vcl::CodePageCoverage::CP861])
1060 : fprintf(stderr, "CP861\n");
1061 : if (rIn[vcl::CodePageCoverage::CP860])
1062 : fprintf(stderr, "CP860\n");
1063 : if (rIn[vcl::CodePageCoverage::CP857])
1064 : fprintf(stderr, "CP857\n");
1065 : if (rIn[vcl::CodePageCoverage::CP855])
1066 : fprintf(stderr, "CP855\n");
1067 : if (rIn[vcl::CodePageCoverage::CP852])
1068 : fprintf(stderr, "CP852\n");
1069 : if (rIn[vcl::CodePageCoverage::CP775])
1070 : fprintf(stderr, "CP775\n");
1071 : if (rIn[vcl::CodePageCoverage::CP737])
1072 : fprintf(stderr, "CP737\n");
1073 : if (rIn[vcl::CodePageCoverage::CP780])
1074 : fprintf(stderr, "CP780\n");
1075 : if (rIn[vcl::CodePageCoverage::CP850])
1076 : fprintf(stderr, "CP850\n");
1077 : if (rIn[vcl::CodePageCoverage::CP437])
1078 : fprintf(stderr, "CP437\n");
1079 : }
1080 : #endif
1081 :
1082 0 : boost::dynamic_bitset<sal_uInt32> getMaskByScriptType(sal_Int16 nScriptType)
1083 : {
1084 0 : boost::dynamic_bitset<sal_uInt32> aMask(vcl::UnicodeCoverage::MAX_UC_ENUM);
1085 0 : aMask.set();
1086 :
1087 0 : for (size_t i = 0; i < vcl::UnicodeCoverage::MAX_UC_ENUM; ++i)
1088 : {
1089 : using vcl::UnicodeCoverage::UnicodeCoverageEnum;
1090 0 : UScriptCode eScriptCode = otCoverageToScript(static_cast<UnicodeCoverageEnum>(i));
1091 0 : if (unicode::getScriptClassFromUScriptCode(eScriptCode) == nScriptType)
1092 0 : aMask.set(i, false);
1093 : }
1094 :
1095 0 : return aMask;
1096 : }
1097 :
1098 : //false for all bits considered "Latin" by LibreOffice
1099 0 : boost::dynamic_bitset<sal_uInt32> getLatinMask()
1100 : {
1101 0 : static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::LATIN));
1102 0 : return aMask;
1103 : }
1104 :
1105 : //false for all bits considered "Asian" by LibreOffice
1106 0 : boost::dynamic_bitset<sal_uInt32> getCJKMask()
1107 : {
1108 0 : static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::ASIAN));
1109 0 : return aMask;
1110 : }
1111 :
1112 : //false for all bits considered "Complex" by LibreOffice
1113 0 : boost::dynamic_bitset<sal_uInt32> getCTLMask()
1114 : {
1115 0 : static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::COMPLEX));
1116 0 : return aMask;
1117 : }
1118 :
1119 : //false for all bits considered "WEAK" by LibreOffice
1120 0 : boost::dynamic_bitset<sal_uInt32> getWeakMask()
1121 : {
1122 0 : static boost::dynamic_bitset<sal_uInt32> aMask(getMaskByScriptType(com::sun::star::i18n::ScriptType::WEAK));
1123 0 : return aMask;
1124 : }
1125 :
1126 : //Nearly every font supports some basic Latin
1127 0 : boost::dynamic_bitset<sal_uInt32> getCommonLatnSubsetMask()
1128 : {
1129 0 : boost::dynamic_bitset<sal_uInt32> aMask(vcl::UnicodeCoverage::MAX_UC_ENUM);
1130 0 : aMask.set();
1131 0 : aMask.set(vcl::UnicodeCoverage::BASIC_LATIN, false);
1132 0 : aMask.set(vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT, false);
1133 0 : aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_A, false);
1134 0 : aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_B, false);
1135 0 : aMask.set(vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL, false);
1136 0 : return aMask;
1137 : }
1138 :
1139 0 : UScriptCode getScript(const vcl::FontCapabilities &rFontCapabilities)
1140 : {
1141 : using vcl::UnicodeCoverage::UnicodeCoverageEnum;
1142 :
1143 0 : boost::dynamic_bitset<sal_uInt32> aMasked = rFontCapabilities.maUnicodeRange & getWeakMask();
1144 :
1145 0 : if (aMasked.count() == 1)
1146 0 : return otCoverageToScript(static_cast<UnicodeCoverageEnum>(aMasked.find_first()));
1147 :
1148 0 : if (aMasked[vcl::UnicodeCoverage::ARABIC])
1149 : {
1150 0 : aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A, false);
1151 0 : aMasked.set(vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B, false);
1152 0 : aMasked.set(vcl::UnicodeCoverage::NKO, false);
1153 : //Probably strongly tuned for Arabic
1154 0 : if (aMasked.count() == 1)
1155 0 : return USCRIPT_ARABIC;
1156 0 : if (aMasked.count() == 2 && aMasked[vcl::UnicodeCoverage::SYRIAC])
1157 0 : return USCRIPT_SYRIAC;
1158 : }
1159 :
1160 0 : if (aMasked[vcl::UnicodeCoverage::DEVANAGARI])
1161 : {
1162 0 : aMasked.set(vcl::UnicodeCoverage::DEVANAGARI, false);
1163 : //Probably strongly tuned for a single Indic script
1164 0 : if (aMasked.count() == 1)
1165 0 : return otCoverageToScript(static_cast<UnicodeCoverageEnum>(aMasked.find_first()));
1166 : }
1167 :
1168 0 : aMasked.set(vcl::UnicodeCoverage::GREEK_EXTENDED, false);
1169 0 : aMasked.set(vcl::UnicodeCoverage::GREEK_AND_COPTIC, false);
1170 0 : if (aMasked.count() == 1)
1171 0 : return otCoverageToScript(static_cast<UnicodeCoverageEnum>(aMasked.find_first()));
1172 :
1173 0 : if (aMasked[vcl::UnicodeCoverage::CYRILLIC])
1174 : {
1175 : //Probably strongly tuned for Georgian
1176 0 : if (aMasked.count() == 2 && aMasked[vcl::UnicodeCoverage::GEORGIAN])
1177 0 : return USCRIPT_GEORGIAN;
1178 : }
1179 :
1180 0 : aMasked &= getCJKMask();
1181 :
1182 0 : aMasked.set(vcl::UnicodeCoverage::CYRILLIC, false);
1183 0 : aMasked.set(vcl::UnicodeCoverage::THAI, false);
1184 0 : aMasked.set(vcl::UnicodeCoverage::DESERET, false);
1185 0 : aMasked.set(vcl::UnicodeCoverage::PHAGS_PA, false);
1186 :
1187 : //So, possibly a CJK font
1188 0 : if (!aMasked.count() && !rFontCapabilities.maCodePageRange.empty())
1189 : {
1190 0 : boost::dynamic_bitset<sal_uInt32> aCJKCodePageMask(vcl::CodePageCoverage::MAX_CP_ENUM);
1191 0 : aCJKCodePageMask.set(vcl::CodePageCoverage::CP932);
1192 0 : aCJKCodePageMask.set(vcl::CodePageCoverage::CP936);
1193 0 : aCJKCodePageMask.set(vcl::CodePageCoverage::CP949);
1194 0 : aCJKCodePageMask.set(vcl::CodePageCoverage::CP950);
1195 0 : aCJKCodePageMask.set(vcl::CodePageCoverage::CP1361);
1196 : boost::dynamic_bitset<sal_uInt32> aMaskedCodePage =
1197 0 : rFontCapabilities.maCodePageRange & aCJKCodePageMask;
1198 : //fold Korean
1199 0 : if (aMaskedCodePage[vcl::CodePageCoverage::CP1361])
1200 : {
1201 0 : aMaskedCodePage.set(vcl::CodePageCoverage::CP949);
1202 0 : aMaskedCodePage.set(vcl::CodePageCoverage::CP1361, false);
1203 : }
1204 :
1205 0 : if (aMaskedCodePage.count() == 1)
1206 : {
1207 0 : if (aMaskedCodePage[vcl::CodePageCoverage::CP932])
1208 0 : return USCRIPT_JAPANESE;
1209 0 : if (aMaskedCodePage[vcl::CodePageCoverage::CP949])
1210 0 : return USCRIPT_KOREAN;
1211 0 : if (aMaskedCodePage[vcl::CodePageCoverage::CP936])
1212 0 : return USCRIPT_SIMPLIFIED_HAN;
1213 0 : if (aMaskedCodePage[vcl::CodePageCoverage::CP950])
1214 0 : return USCRIPT_TRADITIONAL_HAN;
1215 : }
1216 :
1217 0 : if (aMaskedCodePage.count())
1218 0 : return USCRIPT_HAN;
1219 : }
1220 :
1221 0 : return USCRIPT_COMMON;
1222 : }
1223 : }
1224 :
1225 : namespace
1226 : {
1227 0 : UScriptCode attemptToDisambiguateHan(UScriptCode eScript, OutputDevice &rDevice)
1228 : {
1229 : //If we're a CJK font, see if we seem to be tuned for C, J or K
1230 0 : if (eScript == USCRIPT_HAN)
1231 : {
1232 0 : const vcl::Font &rFont = rDevice.GetFont();
1233 :
1234 0 : bool bKore = false, bJpan = false, bHant = false, bHans = false;
1235 :
1236 0 : const sal_Unicode aKorean[] = { 0x3131 };
1237 0 : OUString sKorean(aKorean, SAL_N_ELEMENTS(aKorean));
1238 0 : if (-1 == rDevice.HasGlyphs(rFont, sKorean))
1239 0 : bKore = true;
1240 :
1241 0 : const sal_Unicode aJapanese[] = { 0x3007, 0x9F9D };
1242 0 : OUString sJapanese(aJapanese, SAL_N_ELEMENTS(aJapanese));
1243 0 : if (-1 == rDevice.HasGlyphs(rFont, sJapanese))
1244 0 : bJpan = true;
1245 :
1246 0 : const sal_Unicode aTraditionalChinese[] = { 0x570B };
1247 0 : OUString sTraditionalChinese(aTraditionalChinese, SAL_N_ELEMENTS(aTraditionalChinese));
1248 0 : if (-1 == rDevice.HasGlyphs(rFont, sTraditionalChinese))
1249 0 : bHant = true;
1250 :
1251 0 : const sal_Unicode aSimplifiedChinese[] = { 0x56FD };
1252 0 : OUString sSimplifiedChinese(aSimplifiedChinese, SAL_N_ELEMENTS(aSimplifiedChinese));
1253 0 : if (-1 == rDevice.HasGlyphs(rFont, sSimplifiedChinese))
1254 0 : bHans = true;
1255 :
1256 0 : if (bKore && !bJpan && !bHans)
1257 0 : eScript = USCRIPT_KOREAN;
1258 0 : else if (bJpan && !bKore && !bHans)
1259 0 : eScript = USCRIPT_JAPANESE;
1260 0 : else if (bHant && !bHans && !bKore && !bJpan)
1261 0 : eScript = USCRIPT_TRADITIONAL_HAN;
1262 0 : else if (bHans && !bHant && !bKore && !bJpan)
1263 0 : eScript = USCRIPT_SIMPLIFIED_HAN;
1264 : //otherwise fall-through as USCRIPT_HAN and expect a combind Hant/Hans preview
1265 : }
1266 0 : return eScript;
1267 : }
1268 : }
1269 :
1270 0 : OUString makeShortRepresentativeTextForSelectedFont(OutputDevice &rDevice)
1271 : {
1272 0 : UScriptCode eScript = lcl_getHardCodedScriptNameForFont(rDevice);
1273 0 : if (eScript == USCRIPT_INVALID_CODE)
1274 : {
1275 0 : vcl::FontCapabilities aFontCapabilities;
1276 0 : if (!rDevice.GetFontCapabilities(aFontCapabilities))
1277 0 : return OUString();
1278 :
1279 : #if OSL_DEBUG_LEVEL > 2
1280 : lcl_dump_unicode_coverage(aFontCapabilities.maUnicodeRange);
1281 : lcl_dump_codepage_coverage(aFontCapabilities.maCodePageRange);
1282 : #endif
1283 :
1284 0 : aFontCapabilities.maUnicodeRange &= getCommonLatnSubsetMask();
1285 :
1286 : //If this font is probably tuned to display a single non-Latin
1287 : //script and the font name is itself in Latin, then show a small
1288 : //chunk of representative text for that script
1289 0 : eScript = getScript(aFontCapabilities);
1290 0 : if (eScript == USCRIPT_COMMON)
1291 0 : return OUString();
1292 :
1293 0 : eScript = attemptToDisambiguateHan(eScript, rDevice);
1294 : }
1295 :
1296 0 : OUString sSampleText = makeShortRepresentativeTextForScript(eScript);
1297 0 : bool bHasSampleTextGlyphs = (-1 == rDevice.HasGlyphs(rDevice.GetFont(), sSampleText));
1298 0 : return bHasSampleTextGlyphs ? sSampleText : OUString();
1299 : }
1300 :
1301 0 : UScriptCode otCoverageToScript(vcl::UnicodeCoverage::UnicodeCoverageEnum eOTCoverage)
1302 : {
1303 0 : UScriptCode eRet = USCRIPT_COMMON;
1304 0 : switch (eOTCoverage)
1305 : {
1306 : case vcl::UnicodeCoverage::BASIC_LATIN:
1307 : case vcl::UnicodeCoverage::LATIN_1_SUPPLEMENT:
1308 : case vcl::UnicodeCoverage::LATIN_EXTENDED_A:
1309 : case vcl::UnicodeCoverage::LATIN_EXTENDED_B:
1310 0 : eRet = USCRIPT_LATIN;
1311 0 : break;
1312 : case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS:
1313 0 : eRet = USCRIPT_INHERITED;
1314 0 : break;
1315 : case vcl::UnicodeCoverage::GREEK_AND_COPTIC:
1316 0 : eRet = USCRIPT_GREEK;
1317 0 : break;
1318 : case vcl::UnicodeCoverage::COPTIC:
1319 0 : eRet = USCRIPT_COPTIC;
1320 0 : break;
1321 : case vcl::UnicodeCoverage::CYRILLIC:
1322 0 : eRet = USCRIPT_CYRILLIC;
1323 0 : break;
1324 : case vcl::UnicodeCoverage::ARMENIAN:
1325 0 : eRet = USCRIPT_ARMENIAN;
1326 0 : break;
1327 : case vcl::UnicodeCoverage::HEBREW:
1328 0 : eRet = USCRIPT_HEBREW;
1329 0 : break;
1330 : case vcl::UnicodeCoverage::VAI:
1331 0 : eRet = USCRIPT_VAI;
1332 0 : break;
1333 : case vcl::UnicodeCoverage::ARABIC:
1334 0 : eRet = USCRIPT_ARABIC;
1335 0 : break;
1336 : case vcl::UnicodeCoverage::NKO:
1337 0 : eRet = USCRIPT_NKO;
1338 0 : break;
1339 : case vcl::UnicodeCoverage::DEVANAGARI:
1340 0 : eRet = USCRIPT_DEVANAGARI;
1341 0 : break;
1342 : case vcl::UnicodeCoverage::BENGALI:
1343 0 : eRet = USCRIPT_BENGALI;
1344 0 : break;
1345 : case vcl::UnicodeCoverage::GURMUKHI:
1346 0 : eRet = USCRIPT_GURMUKHI;
1347 0 : break;
1348 : case vcl::UnicodeCoverage::GUJARATI:
1349 0 : eRet = USCRIPT_GUJARATI;
1350 0 : break;
1351 : case vcl::UnicodeCoverage::ODIA:
1352 0 : eRet = USCRIPT_ORIYA;
1353 0 : break;
1354 : case vcl::UnicodeCoverage::TAMIL:
1355 0 : eRet = USCRIPT_TAMIL;
1356 0 : break;
1357 : case vcl::UnicodeCoverage::TELUGU:
1358 0 : eRet = USCRIPT_TELUGU;
1359 0 : break;
1360 : case vcl::UnicodeCoverage::KANNADA:
1361 0 : eRet = USCRIPT_KANNADA;
1362 0 : break;
1363 : case vcl::UnicodeCoverage::MALAYALAM:
1364 0 : eRet = USCRIPT_MALAYALAM;
1365 0 : break;
1366 : case vcl::UnicodeCoverage::THAI:
1367 0 : eRet = USCRIPT_THAI;
1368 0 : break;
1369 : case vcl::UnicodeCoverage::LAO:
1370 0 : eRet = USCRIPT_LAO;
1371 0 : break;
1372 : case vcl::UnicodeCoverage::GEORGIAN:
1373 0 : eRet = USCRIPT_GEORGIAN;
1374 0 : break;
1375 : case vcl::UnicodeCoverage::BALINESE:
1376 0 : eRet = USCRIPT_BALINESE;
1377 0 : break;
1378 : case vcl::UnicodeCoverage::HANGUL_JAMO:
1379 0 : eRet = USCRIPT_HANGUL;
1380 0 : break;
1381 : case vcl::UnicodeCoverage::LATIN_EXTENDED_ADDITIONAL:
1382 0 : eRet = USCRIPT_LATIN;
1383 0 : break;
1384 : case vcl::UnicodeCoverage::GREEK_EXTENDED:
1385 0 : eRet = USCRIPT_GREEK;
1386 0 : break;
1387 : case vcl::UnicodeCoverage::CURRENCY_SYMBOLS:
1388 0 : eRet = USCRIPT_SYMBOLS;
1389 0 : break;
1390 : case vcl::UnicodeCoverage::COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS:
1391 0 : eRet = USCRIPT_INHERITED;
1392 0 : break;
1393 : case vcl::UnicodeCoverage::LETTERLIKE_SYMBOLS:
1394 : case vcl::UnicodeCoverage::NUMBER_FORMS:
1395 : case vcl::UnicodeCoverage::ARROWS:
1396 0 : eRet = USCRIPT_SYMBOLS;
1397 0 : break;
1398 : case vcl::UnicodeCoverage::MATHEMATICAL_OPERATORS:
1399 0 : eRet = USCRIPT_MATHEMATICAL_NOTATION;
1400 0 : break;
1401 : case vcl::UnicodeCoverage::MISCELLANEOUS_TECHNICAL:
1402 : case vcl::UnicodeCoverage::OPTICAL_CHARACTER_RECOGNITION:
1403 : case vcl::UnicodeCoverage::BOX_DRAWING:
1404 : case vcl::UnicodeCoverage::BLOCK_ELEMENTS:
1405 : case vcl::UnicodeCoverage::GEOMETRIC_SHAPES:
1406 : case vcl::UnicodeCoverage::MISCELLANEOUS_SYMBOLS:
1407 : case vcl::UnicodeCoverage::DINGBATS:
1408 : case vcl::UnicodeCoverage::CJK_SYMBOLS_AND_PUNCTUATION:
1409 0 : eRet = USCRIPT_SYMBOLS;
1410 0 : break;
1411 : case vcl::UnicodeCoverage::HIRAGANA:
1412 0 : eRet = USCRIPT_HIRAGANA;
1413 0 : break;
1414 : case vcl::UnicodeCoverage::KATAKANA:
1415 0 : eRet = USCRIPT_KATAKANA;
1416 0 : break;
1417 : case vcl::UnicodeCoverage::BOPOMOFO:
1418 0 : eRet = USCRIPT_BOPOMOFO;
1419 0 : break;
1420 : case vcl::UnicodeCoverage::HANGUL_COMPATIBILITY_JAMO:
1421 0 : eRet = USCRIPT_HANGUL;
1422 0 : break;
1423 : case vcl::UnicodeCoverage::PHAGS_PA:
1424 0 : eRet = USCRIPT_PHAGS_PA;
1425 0 : break;
1426 : case vcl::UnicodeCoverage::ENCLOSED_CJK_LETTERS_AND_MONTHS:
1427 0 : eRet = USCRIPT_HANGUL;
1428 0 : break;
1429 : case vcl::UnicodeCoverage::CJK_COMPATIBILITY:
1430 0 : eRet = USCRIPT_HAN;
1431 0 : break;
1432 : case vcl::UnicodeCoverage::HANGUL_SYLLABLES:
1433 0 : eRet = USCRIPT_HANGUL;
1434 0 : break;
1435 : case vcl::UnicodeCoverage::PHOENICIAN:
1436 0 : eRet = USCRIPT_PHOENICIAN;
1437 0 : break;
1438 : case vcl::UnicodeCoverage::CJK_UNIFIED_IDEOGRAPHS:
1439 : case vcl::UnicodeCoverage::CJK_STROKES:
1440 0 : eRet = USCRIPT_HAN;
1441 0 : break;
1442 : case vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_A:
1443 0 : eRet = USCRIPT_ARABIC;
1444 0 : break;
1445 : case vcl::UnicodeCoverage::COMBINING_HALF_MARKS:
1446 0 : eRet = USCRIPT_INHERITED;
1447 0 : break;
1448 : case vcl::UnicodeCoverage::ARABIC_PRESENTATION_FORMS_B:
1449 0 : eRet = USCRIPT_ARABIC;
1450 0 : break;
1451 : case vcl::UnicodeCoverage::TIBETAN:
1452 0 : eRet = USCRIPT_TIBETAN;
1453 0 : break;
1454 : case vcl::UnicodeCoverage::SYRIAC:
1455 0 : eRet = USCRIPT_SYRIAC;
1456 0 : break;
1457 : case vcl::UnicodeCoverage::THAANA:
1458 0 : eRet = USCRIPT_THAANA;
1459 0 : break;
1460 : case vcl::UnicodeCoverage::SINHALA:
1461 0 : eRet = USCRIPT_SINHALA;
1462 0 : break;
1463 : case vcl::UnicodeCoverage::MYANMAR:
1464 0 : eRet = USCRIPT_MYANMAR;
1465 0 : break;
1466 : case vcl::UnicodeCoverage::ETHIOPIC:
1467 0 : eRet = USCRIPT_ETHIOPIC;
1468 0 : break;
1469 : case vcl::UnicodeCoverage::CHEROKEE:
1470 0 : eRet = USCRIPT_CHEROKEE;
1471 0 : break;
1472 : case vcl::UnicodeCoverage::UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS:
1473 0 : eRet = USCRIPT_CANADIAN_ABORIGINAL;
1474 0 : break;
1475 : case vcl::UnicodeCoverage::OGHAM:
1476 0 : eRet = USCRIPT_OGHAM;
1477 0 : break;
1478 : case vcl::UnicodeCoverage::RUNIC:
1479 0 : eRet = USCRIPT_RUNIC;
1480 0 : break;
1481 : case vcl::UnicodeCoverage::KHMER:
1482 0 : eRet = USCRIPT_KHMER;
1483 0 : break;
1484 : case vcl::UnicodeCoverage::MONGOLIAN:
1485 0 : eRet = USCRIPT_MONGOLIAN;
1486 0 : break;
1487 : case vcl::UnicodeCoverage::BRAILLE_PATTERNS:
1488 0 : eRet = USCRIPT_BRAILLE;
1489 0 : break;
1490 : case vcl::UnicodeCoverage::YI_SYLLABLES:
1491 0 : eRet = USCRIPT_YI;
1492 0 : break;
1493 : case vcl::UnicodeCoverage::TAGALOG:
1494 0 : eRet = USCRIPT_TAGALOG;
1495 0 : break;
1496 : case vcl::UnicodeCoverage::OLD_ITALIC:
1497 0 : eRet = USCRIPT_OLD_ITALIC;
1498 0 : break;
1499 : case vcl::UnicodeCoverage::GOTHIC:
1500 0 : eRet = USCRIPT_GOTHIC;
1501 0 : break;
1502 : case vcl::UnicodeCoverage::DESERET:
1503 0 : eRet = USCRIPT_DESERET;
1504 0 : break;
1505 : case vcl::UnicodeCoverage::BYZANTINE_MUSICAL_SYMBOLS:
1506 : case vcl::UnicodeCoverage::MATHEMATICAL_ALPHANUMERIC_SYMBOLS:
1507 : case vcl::UnicodeCoverage::PRIVATE_USE_PLANE_15:
1508 0 : eRet = USCRIPT_SYMBOLS;
1509 0 : break;
1510 : case vcl::UnicodeCoverage::VARIATION_SELECTORS:
1511 0 : eRet = USCRIPT_INHERITED;
1512 0 : break;
1513 : case vcl::UnicodeCoverage::TAGS:
1514 0 : eRet = USCRIPT_SYMBOLS;
1515 0 : break;
1516 : case vcl::UnicodeCoverage::LIMBU:
1517 0 : eRet = USCRIPT_LIMBU;
1518 0 : break;
1519 : case vcl::UnicodeCoverage::TAI_LE:
1520 0 : eRet = USCRIPT_TAI_LE;
1521 0 : break;
1522 : case vcl::UnicodeCoverage::NEW_TAI_LUE:
1523 0 : eRet = USCRIPT_NEW_TAI_LUE;
1524 0 : break;
1525 : case vcl::UnicodeCoverage::BUGINESE:
1526 0 : eRet = USCRIPT_BUGINESE;
1527 0 : break;
1528 : case vcl::UnicodeCoverage::GLAGOLITIC:
1529 0 : eRet = USCRIPT_GLAGOLITIC;
1530 0 : break;
1531 : case vcl::UnicodeCoverage::TIFINAGH:
1532 0 : eRet = USCRIPT_TIFINAGH;
1533 0 : break;
1534 : case vcl::UnicodeCoverage::YIJING_HEXAGRAM_SYMBOLS:
1535 0 : eRet = USCRIPT_SYMBOLS;
1536 0 : break;
1537 : case vcl::UnicodeCoverage::SYLOTI_NAGRI:
1538 0 : eRet = USCRIPT_SYLOTI_NAGRI;
1539 0 : break;
1540 : case vcl::UnicodeCoverage::LINEAR_B_SYLLABARY:
1541 0 : eRet = USCRIPT_LINEAR_B;
1542 0 : break;
1543 : case vcl::UnicodeCoverage::ANCIENT_GREEK_NUMBERS:
1544 0 : eRet = USCRIPT_GREEK;
1545 0 : break;
1546 : case vcl::UnicodeCoverage::UGARITIC:
1547 0 : eRet = USCRIPT_UGARITIC;
1548 0 : break;
1549 : case vcl::UnicodeCoverage::OLD_PERSIAN:
1550 0 : eRet = USCRIPT_OLD_PERSIAN;
1551 0 : break;
1552 : case vcl::UnicodeCoverage::SHAVIAN:
1553 0 : eRet = USCRIPT_SHAVIAN;
1554 0 : break;
1555 : case vcl::UnicodeCoverage::OSMANYA:
1556 0 : eRet = USCRIPT_OSMANYA;
1557 0 : break;
1558 : case vcl::UnicodeCoverage::CYPRIOT_SYLLABARY:
1559 0 : eRet = USCRIPT_CYPRIOT;
1560 0 : break;
1561 : case vcl::UnicodeCoverage::KHAROSHTHI:
1562 0 : eRet = USCRIPT_KHAROSHTHI;
1563 0 : break;
1564 : case vcl::UnicodeCoverage::CUNEIFORM:
1565 0 : eRet = USCRIPT_CUNEIFORM;
1566 0 : break;
1567 : case vcl::UnicodeCoverage::SUNDANESE:
1568 0 : eRet = USCRIPT_SUNDANESE;
1569 0 : break;
1570 : case vcl::UnicodeCoverage::LEPCHA:
1571 0 : eRet = USCRIPT_LEPCHA;
1572 0 : break;
1573 : case vcl::UnicodeCoverage::OL_CHIKI:
1574 0 : eRet = USCRIPT_OL_CHIKI;
1575 0 : break;
1576 : case vcl::UnicodeCoverage::SAURASHTRA:
1577 0 : eRet = USCRIPT_SAURASHTRA;
1578 0 : break;
1579 : case vcl::UnicodeCoverage::KAYAH_LI:
1580 0 : eRet = USCRIPT_KAYAH_LI;
1581 0 : break;
1582 : case vcl::UnicodeCoverage::REJANG:
1583 0 : eRet = USCRIPT_REJANG;
1584 0 : break;
1585 : case vcl::UnicodeCoverage::CHAM:
1586 0 : eRet = USCRIPT_CHAM;
1587 0 : break;
1588 : case vcl::UnicodeCoverage::CARIAN:
1589 0 : eRet = USCRIPT_CARIAN;
1590 0 : break;
1591 : case vcl::UnicodeCoverage::DOMINO_TILES:
1592 : case vcl::UnicodeCoverage::TAI_XUAN_JING_SYMBOLS:
1593 : case vcl::UnicodeCoverage::COUNTING_ROD_NUMERALS:
1594 : case vcl::UnicodeCoverage::ANCIENT_SYMBOLS:
1595 : case vcl::UnicodeCoverage::PHAISTOS_DISC:
1596 0 : eRet = USCRIPT_SYMBOLS;
1597 0 : break;
1598 : case vcl::UnicodeCoverage::IPA_EXTENSIONS:
1599 : case vcl::UnicodeCoverage::SPECIALS:
1600 : case vcl::UnicodeCoverage::HALFWIDTH_AND_FULLWIDTH_FORMS:
1601 : case vcl::UnicodeCoverage::VERTICAL_FORMS:
1602 : case vcl::UnicodeCoverage::SMALL_FORM_VARIANTS:
1603 : case vcl::UnicodeCoverage::ALPHABETIC_PRESENTATION_FORMS:
1604 : case vcl::UnicodeCoverage::PRIVATE_USE_AREA_PLANE_0:
1605 : case vcl::UnicodeCoverage::NONPLANE_0:
1606 : case vcl::UnicodeCoverage::ENCLOSED_ALPHANUMERICS:
1607 : case vcl::UnicodeCoverage::CONTROL_PICTURES:
1608 : case vcl::UnicodeCoverage::SUPERSCRIPTS_AND_SUBSCRIPTS:
1609 : case vcl::UnicodeCoverage::GENERAL_PUNCTUATION:
1610 : case vcl::UnicodeCoverage::SPACING_MODIFIER_LETTERS:
1611 : case vcl::UnicodeCoverage::RESERVED1:
1612 : case vcl::UnicodeCoverage::RESERVED2:
1613 : case vcl::UnicodeCoverage::RESERVED3:
1614 : case vcl::UnicodeCoverage::RESERVED4:
1615 : case vcl::UnicodeCoverage::RESERVED5:
1616 : case vcl::UnicodeCoverage::MAX_UC_ENUM:
1617 0 : break;
1618 : }
1619 0 : return eRet;
1620 : }
1621 :
1622 0 : OUString makeRepresentativeTextForFont(sal_Int16 nScriptType, const vcl::Font &rFont)
1623 : {
1624 0 : OUString sRet(makeRepresentativeTextForLanguage(rFont.GetLanguage()));
1625 :
1626 0 : ScopedVclPtrInstance< VirtualDevice > aDevice;
1627 0 : if (sRet.isEmpty() || (-1 != aDevice->HasGlyphs(rFont, sRet)))
1628 : {
1629 0 : aDevice->SetFont(rFont);
1630 0 : vcl::FontCapabilities aFontCapabilities;
1631 0 : if (aDevice->GetFontCapabilities(aFontCapabilities))
1632 : {
1633 : #if OSL_DEBUG_LEVEL > 2
1634 : lcl_dump_unicode_coverage(aFontCapabilities.maUnicodeRange);
1635 : #endif
1636 :
1637 0 : aFontCapabilities.maUnicodeRange &= getWeakMask();
1638 :
1639 0 : if (nScriptType != com::sun::star::i18n::ScriptType::ASIAN)
1640 : {
1641 0 : aFontCapabilities.maUnicodeRange &= getCJKMask();
1642 0 : aFontCapabilities.maCodePageRange.clear();
1643 : }
1644 0 : if (nScriptType != com::sun::star::i18n::ScriptType::LATIN)
1645 0 : aFontCapabilities.maUnicodeRange &= getLatinMask();
1646 0 : if (nScriptType != com::sun::star::i18n::ScriptType::COMPLEX)
1647 0 : aFontCapabilities.maUnicodeRange &= getCTLMask();
1648 :
1649 : #if OSL_DEBUG_LEVEL > 2
1650 : fprintf(stderr, "minimal\n");
1651 : lcl_dump_unicode_coverage(aFontCapabilities.maUnicodeRange);
1652 : lcl_dump_codepage_coverage(aFontCapabilities.maCodePageRange);
1653 : #endif
1654 :
1655 0 : UScriptCode eScript = getScript(aFontCapabilities);
1656 :
1657 0 : if (nScriptType == com::sun::star::i18n::ScriptType::ASIAN)
1658 0 : eScript = attemptToDisambiguateHan(eScript, *aDevice.get());
1659 :
1660 0 : sRet = makeRepresentativeTextForScript(eScript);
1661 : }
1662 :
1663 0 : if (sRet.isEmpty())
1664 : {
1665 0 : if (nScriptType == com::sun::star::i18n::ScriptType::COMPLEX)
1666 : {
1667 0 : sRet = makeRepresentativeTextForScript(USCRIPT_HEBREW);
1668 0 : if (-1 != aDevice->HasGlyphs(rFont, sRet))
1669 : {
1670 0 : sRet = makeMinimalTextForScript(USCRIPT_HEBREW);
1671 0 : if (-1 != aDevice->HasGlyphs(rFont, sRet))
1672 0 : sRet = makeRepresentativeTextForScript(USCRIPT_ARABIC);
1673 : }
1674 : }
1675 0 : else if (nScriptType == com::sun::star::i18n::ScriptType::LATIN)
1676 0 : sRet = makeRepresentativeTextForScript(USCRIPT_LATIN);
1677 0 : }
1678 : }
1679 :
1680 0 : return sRet;
1681 : }
1682 :
1683 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|