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 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <string.h>
21 :
22 : #include <comphelper/string.hxx>
23 : #include <tools/debug.hxx>
24 : #include <tools/fract.hxx>
25 : #include <i18nlangtag/mslangid.hxx>
26 : #include <vcl/window.hxx>
27 : #include <vcl/svapp.hxx>
28 : #include <vcl/wrkwin.hxx>
29 : #include <vcl/settings.hxx>
30 : #include <sal/macros.h>
31 : #include <svtools/svtools.hrc>
32 : #include <svtools/svtresid.hxx>
33 : #include <svtools/ctrltool.hxx>
34 : #include <o3tl/typed_flags_set.hxx>
35 :
36 : // Standard Fontgroessen fuer scalierbare Fonts
37 : const sal_IntPtr FontList::aStdSizeAry[] =
38 : {
39 : 60,
40 : 70,
41 : 80,
42 : 90,
43 : 100,
44 : 105,
45 : 110,
46 : 120,
47 : 130,
48 : 140,
49 : 150,
50 : 160,
51 : 180,
52 : 200,
53 : 220,
54 : 240,
55 : 260,
56 : 280,
57 : 320,
58 : 360,
59 : 400,
60 : 440,
61 : 480,
62 : 540,
63 : 600,
64 : 660,
65 : 720,
66 : 800,
67 : 880,
68 : 960,
69 : 0
70 : };
71 :
72 1598464 : class ImplFontListFontInfo : public vcl::FontInfo
73 : {
74 : friend class FontList;
75 :
76 : private:
77 : VclPtr<OutputDevice> mpDevice;
78 : ImplFontListFontInfo* mpNext;
79 :
80 : public:
81 1601363 : ImplFontListFontInfo( const vcl::FontInfo& rInfo,
82 : OutputDevice* pDev ) :
83 1601363 : vcl::FontInfo( rInfo ), mpNext(NULL)
84 : {
85 1601363 : mpDevice = pDev;
86 1601363 : }
87 :
88 1665 : OutputDevice* GetDevice() const { return mpDevice; }
89 : };
90 :
91 : enum class FontListFontNameType
92 : {
93 : NONE = 0x00,
94 : PRINTER = 0x01,
95 : SCREEN = 0x02,
96 : };
97 : namespace o3tl
98 : {
99 : template<> struct typed_flags<FontListFontNameType> : is_typed_flags<FontListFontNameType, 0x3> {};
100 : }
101 :
102 616448 : class ImplFontListNameInfo
103 : {
104 : friend class FontList;
105 :
106 : private:
107 : OUString maSearchName;
108 : ImplFontListFontInfo* mpFirst;
109 : FontListFontNameType mnType;
110 :
111 617566 : ImplFontListNameInfo(const OUString& rSearchName)
112 : : maSearchName(rSearchName)
113 : , mpFirst(NULL)
114 617566 : , mnType(FontListFontNameType::NONE)
115 : {
116 617566 : }
117 : };
118 :
119 : //sort normal to the start
120 1450562 : static int sortWeightValue(FontWeight eWeight)
121 : {
122 1450562 : if (eWeight < WEIGHT_NORMAL)
123 14362 : return eWeight + 1;
124 1436200 : if (eWeight > WEIGHT_NORMAL)
125 775548 : return eWeight - 1;
126 660652 : return 0; // eWeight == WEIGHT_NORMAL
127 : }
128 :
129 1953232 : static sal_Int32 ImplCompareFontInfo( ImplFontListFontInfo* pInfo1,
130 : ImplFontListFontInfo* pInfo2 )
131 : {
132 : //Sort non italic before italics
133 1953232 : if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
134 323145 : return -1;
135 1630087 : else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
136 904806 : return 1;
137 :
138 : //Sort normal weight to the start, followed by lightest to heaviest weights
139 725281 : int nWeight1 = sortWeightValue(pInfo1->GetWeight());
140 725281 : int nWeight2 = sortWeightValue(pInfo2->GetWeight());
141 :
142 725281 : if ( nWeight1 < nWeight2 )
143 7181 : return -1;
144 718100 : else if ( nWeight1 > nWeight2 )
145 689376 : return 1;
146 :
147 28724 : return pInfo1->GetStyleName().compareTo( pInfo2->GetStyleName() );
148 : }
149 :
150 1635174 : static OUString ImplMakeSearchString(const OUString& rStr)
151 : {
152 1635174 : return rStr.toAsciiLowerCase();
153 : }
154 :
155 21769 : static OUString ImplMakeSearchStringFromName(const OUString& rStr)
156 : {
157 : // check for features before alternate font separator
158 21769 : sal_Int32 nColon = rStr.indexOf(':');
159 21769 : sal_Int32 nSemiColon = rStr.indexOf(';');
160 21769 : if (nColon != -1 && (nSemiColon == -1 || nColon < nSemiColon))
161 0 : return ImplMakeSearchString(rStr.getToken( 0, ':' ));
162 21769 : return ImplMakeSearchString(rStr.getToken( 0, ';' ));
163 : }
164 :
165 1635174 : ImplFontListNameInfo* FontList::ImplFind(const OUString& rSearchName, sal_uLong* pIndex) const
166 : {
167 : // Append if there is no enty in the list or if the entry is larger
168 : // then the last one. We only compare to the last entry as the list of VCL
169 : // is returned sorted, which increases the probability that appending
170 : // is more likely
171 1635174 : sal_uLong nCnt = maEntries.size();
172 1635174 : if ( !nCnt )
173 : {
174 7181 : if ( pIndex )
175 7181 : *pIndex = ULONG_MAX;
176 7181 : return NULL;
177 : }
178 : else
179 : {
180 1627993 : const ImplFontListNameInfo* pCmpData = &maEntries[nCnt-1];
181 1627993 : sal_Int32 nComp = rSearchName.compareTo( pCmpData->maSearchName );
182 1627993 : if (nComp > 0)
183 : {
184 33624 : if ( pIndex )
185 26165 : *pIndex = ULONG_MAX;
186 33624 : return NULL;
187 : }
188 1594369 : else if (nComp == 0)
189 77430 : return const_cast<ImplFontListNameInfo*>(pCmpData);
190 : }
191 :
192 : // search fonts in the list
193 : const ImplFontListNameInfo* pCompareData;
194 1516939 : const ImplFontListNameInfo* pFoundData = NULL;
195 1516939 : sal_uLong nLow = 0;
196 1516939 : sal_uLong nHigh = nCnt-1;
197 : sal_uLong nMid;
198 :
199 6334722 : do
200 : {
201 7294156 : nMid = (nLow + nHigh) / 2;
202 7294156 : pCompareData = &maEntries[nMid];
203 7294156 : sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
204 7294156 : if (nComp < 0)
205 : {
206 2942666 : if ( !nMid )
207 38370 : break;
208 2904296 : nHigh = nMid-1;
209 : }
210 : else
211 : {
212 4351490 : if (nComp > 0)
213 3430426 : nLow = nMid + 1;
214 : else
215 : {
216 921064 : pFoundData = pCompareData;
217 921064 : break;
218 : }
219 : }
220 : }
221 : while ( nLow <= nHigh );
222 :
223 1516939 : if ( pIndex )
224 : {
225 1502629 : sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
226 1502629 : if (nComp > 0)
227 238935 : *pIndex = (nMid+1);
228 : else
229 1263694 : *pIndex = nMid;
230 : }
231 :
232 1516939 : return const_cast<ImplFontListNameInfo*>(pFoundData);
233 : }
234 :
235 21769 : ImplFontListNameInfo* FontList::ImplFindByName(const OUString& rStr) const
236 : {
237 21769 : OUString aSearchName = ImplMakeSearchStringFromName(rStr);
238 21769 : return ImplFind( aSearchName, NULL );
239 : }
240 :
241 7452 : void FontList::ImplInsertFonts( OutputDevice* pDevice, bool bAll,
242 : bool bInsertData )
243 : {
244 7452 : rtl_TextEncoding eSystemEncoding = osl_getThreadTextEncoding();
245 :
246 : FontListFontNameType nType;
247 7452 : if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
248 7398 : nType = FontListFontNameType::SCREEN;
249 : else
250 54 : nType = FontListFontNameType::PRINTER;
251 :
252 : // inquire all fonts from the device
253 7452 : int n = pDevice->GetDevFontCount();
254 : sal_uInt16 i;
255 1620857 : for( i = 0; i < n; i++ )
256 : {
257 1613405 : vcl::FontInfo aFontInfo = pDevice->GetDevFont( i );
258 :
259 : // ignore raster-fonts if they are not to be displayed
260 1613405 : if ( !bAll && (aFontInfo.GetType() == TYPE_RASTER) )
261 0 : continue;
262 :
263 3226810 : OUString aSearchName(aFontInfo.GetName());
264 : ImplFontListNameInfo* pData;
265 : sal_uLong nIndex;
266 1613405 : aSearchName = ImplMakeSearchString(aSearchName);
267 1613405 : pData = ImplFind( aSearchName, &nIndex );
268 :
269 1613405 : if ( !pData )
270 : {
271 617566 : if ( bInsertData )
272 : {
273 617566 : ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
274 617566 : pData = new ImplFontListNameInfo( aSearchName );
275 617566 : pData->mpFirst = pNewInfo;
276 617566 : pNewInfo->mpNext = NULL;
277 :
278 617566 : if (nIndex < maEntries.size())
279 584220 : maEntries.insert(maEntries.begin()+nIndex,pData);
280 : else
281 33346 : maEntries.push_back(pData);
282 : }
283 : }
284 : else
285 : {
286 995839 : if ( bInsertData )
287 : {
288 983797 : bool bInsert = true;
289 983797 : ImplFontListFontInfo* pPrev = NULL;
290 983797 : ImplFontListFontInfo* pTemp = pData->mpFirst;
291 983797 : ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
292 3576138 : while ( pTemp )
293 : {
294 1953232 : sal_Int32 eComp = ImplCompareFontInfo( pNewInfo, pTemp );
295 1953232 : if ( eComp <= 0 )
296 : {
297 344688 : if ( eComp == 0 )
298 : {
299 : // Overwrite charset, because charset should match
300 : // with the system charset
301 0 : if ( (pTemp->GetCharSet() != eSystemEncoding) &&
302 0 : (pNewInfo->GetCharSet() == eSystemEncoding) )
303 : {
304 0 : ImplFontListFontInfo* pTemp2 = pTemp->mpNext;
305 0 : *static_cast<vcl::FontInfo*>(pTemp) = *static_cast<vcl::FontInfo*>(pNewInfo);
306 0 : pTemp->mpNext = pTemp2;
307 : }
308 0 : delete pNewInfo;
309 0 : bInsert = false;
310 : }
311 :
312 344688 : break;
313 : }
314 :
315 1608544 : pPrev = pTemp;
316 1608544 : pTemp = pTemp->mpNext;
317 : }
318 :
319 983797 : if ( bInsert )
320 : {
321 983797 : pNewInfo->mpNext = pTemp;
322 983797 : if ( pPrev )
323 962254 : pPrev->mpNext = pNewInfo;
324 : else
325 21543 : pData->mpFirst = pNewInfo;
326 : }
327 : }
328 : }
329 :
330 1613405 : if ( pData )
331 1613405 : pData->mnType |= nType;
332 1613405 : }
333 7452 : }
334 :
335 7398 : FontList::FontList( OutputDevice* pDevice, OutputDevice* pDevice2, bool bAll )
336 : {
337 : // initialise variables
338 7398 : mpDev = pDevice;
339 7398 : mpDev2 = pDevice2;
340 7398 : mpSizeAry = NULL;
341 :
342 : // store style names
343 7398 : maLight = SVT_RESSTR(STR_SVT_STYLE_LIGHT);
344 7398 : maLightItalic = SVT_RESSTR(STR_SVT_STYLE_LIGHT_ITALIC);
345 7398 : maNormal = SVT_RESSTR(STR_SVT_STYLE_NORMAL);
346 7398 : maNormalItalic = SVT_RESSTR(STR_SVT_STYLE_NORMAL_ITALIC);
347 7398 : maBold = SVT_RESSTR(STR_SVT_STYLE_BOLD);
348 7398 : maBoldItalic = SVT_RESSTR(STR_SVT_STYLE_BOLD_ITALIC);
349 7398 : maBlack = SVT_RESSTR(STR_SVT_STYLE_BLACK);
350 7398 : maBlackItalic = SVT_RESSTR(STR_SVT_STYLE_BLACK_ITALIC);
351 :
352 7398 : ImplInsertFonts( pDevice, bAll, true );
353 :
354 : // if required compare to the screen fonts
355 : // in order to map the duplicates to Equal
356 7398 : bool bCompareWindow = false;
357 7398 : if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
358 : {
359 54 : bCompareWindow = true;
360 54 : pDevice2 = Application::GetDefaultDevice();
361 : }
362 :
363 7452 : if ( pDevice2 &&
364 54 : (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
365 54 : ImplInsertFonts( pDevice2, bAll, !bCompareWindow );
366 7398 : }
367 :
368 14760 : FontList::~FontList()
369 : {
370 : // delete SizeArray if required
371 7380 : delete[] mpSizeAry;
372 :
373 : // delete FontInfos
374 : ImplFontListFontInfo *pTemp, *pInfo;
375 7380 : boost::ptr_vector<ImplFontListNameInfo>::iterator it;
376 623828 : for (it = maEntries.begin(); it != maEntries.end(); ++it)
377 : {
378 616448 : pInfo = it->mpFirst;
379 2831360 : while ( pInfo )
380 : {
381 1598464 : pTemp = pInfo->mpNext;
382 1598464 : delete pInfo;
383 1598464 : pInfo = pTemp;
384 : }
385 : }
386 7380 : }
387 :
388 0 : FontList* FontList::Clone() const
389 : {
390 : FontList* pReturn = new FontList(
391 0 : mpDev, mpDev2, GetFontNameCount() == mpDev->GetDevFontCount());
392 0 : return pReturn;
393 : }
394 :
395 10 : const OUString& FontList::GetStyleName(FontWeight eWeight, FontItalic eItalic) const
396 : {
397 10 : if ( eWeight > WEIGHT_BOLD )
398 : {
399 0 : if ( eItalic > ITALIC_NONE )
400 0 : return maBlackItalic;
401 : else
402 0 : return maBlack;
403 : }
404 10 : else if ( eWeight > WEIGHT_MEDIUM )
405 : {
406 0 : if ( eItalic > ITALIC_NONE )
407 0 : return maBoldItalic;
408 : else
409 0 : return maBold;
410 : }
411 10 : else if ( eWeight > WEIGHT_LIGHT )
412 : {
413 10 : if ( eItalic > ITALIC_NONE )
414 0 : return maNormalItalic;
415 : else
416 10 : return maNormal;
417 : }
418 0 : else if ( eWeight != WEIGHT_DONTKNOW )
419 : {
420 0 : if ( eItalic > ITALIC_NONE )
421 0 : return maLightItalic;
422 : else
423 0 : return maLight;
424 : }
425 : else
426 : {
427 0 : if ( eItalic > ITALIC_NONE )
428 0 : return maNormalItalic;
429 : else
430 0 : return maNormal;
431 : }
432 : }
433 :
434 10 : OUString FontList::GetStyleName(const vcl::FontInfo& rInfo) const
435 : {
436 10 : OUString aStyleName = rInfo.GetStyleName();
437 10 : FontWeight eWeight = rInfo.GetWeight();
438 10 : FontItalic eItalic = rInfo.GetItalic();
439 :
440 : // return synthetic Name if no StyleName was set
441 10 : if (aStyleName.isEmpty())
442 10 : aStyleName = GetStyleName(eWeight, eItalic);
443 : else
444 : {
445 : // Translate StyleName to localized name
446 0 : OUString aCompareStyleName = aStyleName.toAsciiLowerCase();
447 0 : aCompareStyleName = comphelper::string::remove(aCompareStyleName, ' ');
448 0 : if (aCompareStyleName == "bold")
449 0 : aStyleName = maBold;
450 0 : else if (aCompareStyleName == "bolditalic")
451 0 : aStyleName = maBoldItalic;
452 0 : else if (aCompareStyleName == "italic")
453 0 : aStyleName = maNormalItalic;
454 0 : else if (aCompareStyleName == "standard")
455 0 : aStyleName = maNormal;
456 0 : else if (aCompareStyleName == "regular")
457 0 : aStyleName = maNormal;
458 0 : else if (aCompareStyleName == "medium")
459 0 : aStyleName = maNormal;
460 0 : else if (aCompareStyleName == "light")
461 0 : aStyleName = maLight;
462 0 : else if (aCompareStyleName == "lightitalic")
463 0 : aStyleName = maLightItalic;
464 0 : else if (aCompareStyleName == "black")
465 0 : aStyleName = maBlack;
466 0 : else if (aCompareStyleName == "blackitalic")
467 0 : aStyleName = maBlackItalic;
468 :
469 : // fix up StyleName, because the PS Printer driver from
470 : // W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
471 : // for Helvetica)
472 0 : if ( eItalic > ITALIC_NONE )
473 : {
474 0 : if ( (aStyleName == maNormal) ||
475 0 : (aStyleName == maBold) ||
476 0 : (aStyleName == maLight) ||
477 0 : (aStyleName == maBlack) )
478 0 : aStyleName = GetStyleName( eWeight, eItalic );
479 0 : }
480 : }
481 :
482 10 : return aStyleName;
483 : }
484 :
485 0 : OUString FontList::GetFontMapText( const vcl::FontInfo& rInfo ) const
486 : {
487 0 : if ( rInfo.GetName().isEmpty() )
488 : {
489 0 : return OUString();
490 : }
491 :
492 : // Search Fontname
493 0 : ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
494 0 : if ( !pData )
495 : {
496 0 : if (maMapNotAvailable.isEmpty())
497 0 : maMapNotAvailable = SVT_RESSTR(STR_SVT_FONTMAP_NOTAVAILABLE);
498 0 : return maMapNotAvailable;
499 : }
500 :
501 : // search for synthetic style
502 0 : FontListFontNameType nType = pData->mnType;
503 0 : const OUString& rStyleName = rInfo.GetStyleName();
504 0 : if (!rStyleName.isEmpty())
505 : {
506 0 : bool bNotSynthetic = false;
507 0 : FontWeight eWeight = rInfo.GetWeight();
508 0 : FontItalic eItalic = rInfo.GetItalic();
509 0 : ImplFontListFontInfo* pFontInfo = pData->mpFirst;
510 0 : while ( pFontInfo )
511 : {
512 0 : if ( (eWeight == pFontInfo->GetWeight()) &&
513 0 : (eItalic == pFontInfo->GetItalic()) )
514 : {
515 0 : bNotSynthetic = true;
516 0 : break;
517 : }
518 :
519 0 : pFontInfo = pFontInfo->mpNext;
520 : }
521 :
522 0 : if ( !bNotSynthetic )
523 : {
524 0 : if (maMapStyleNotAvailable.isEmpty())
525 0 : const_cast<FontList*>(this)->maMapStyleNotAvailable = SVT_RESSTR(STR_SVT_FONTMAP_STYLENOTAVAILABLE);
526 0 : return maMapStyleNotAvailable;
527 : }
528 : }
529 :
530 : // Only Printer-Font?
531 0 : if ( nType == FontListFontNameType::PRINTER )
532 : {
533 0 : if (maMapPrinterOnly.isEmpty())
534 0 : const_cast<FontList*>(this)->maMapPrinterOnly = SVT_RESSTR(STR_SVT_FONTMAP_PRINTERONLY);
535 0 : return maMapPrinterOnly;
536 : }
537 : // Only Screen-Font?
538 0 : else if ( nType == FontListFontNameType::SCREEN
539 0 : && rInfo.GetType() == TYPE_RASTER )
540 : {
541 0 : if (maMapScreenOnly.isEmpty())
542 0 : const_cast<FontList*>(this)->maMapScreenOnly = SVT_RESSTR(STR_SVT_FONTMAP_SCREENONLY);
543 0 : return maMapScreenOnly;
544 : }
545 : else
546 : {
547 0 : if (maMapBoth.isEmpty())
548 0 : const_cast<FontList*>(this)->maMapBoth = SVT_RESSTR(STR_SVT_FONTMAP_BOTH);
549 0 : return maMapBoth;
550 : }
551 : }
552 :
553 : namespace
554 : {
555 19093 : vcl::FontInfo makeMissing(ImplFontListFontInfo* pFontNameInfo, const OUString &rName,
556 : FontWeight eWeight, FontItalic eItalic)
557 : {
558 19093 : vcl::FontInfo aInfo;
559 : // if the fontname matches, we copy as much as possible
560 19093 : if (pFontNameInfo)
561 : {
562 0 : aInfo = *pFontNameInfo;
563 0 : aInfo.SetStyleName(OUString());
564 : }
565 :
566 19093 : aInfo.SetWeight(eWeight);
567 19093 : aInfo.SetItalic(eItalic);
568 :
569 : //If this is a known but uninstalled symbol font which we can remap to
570 : //OpenSymbol then toggle its charset to be a symbol font
571 19093 : if (ConvertChar::GetRecodeData(rName, OUString("OpenSymbol")))
572 13027 : aInfo.SetCharSet(RTL_TEXTENCODING_SYMBOL);
573 :
574 19093 : return aInfo;
575 : }
576 : }
577 :
578 16 : vcl::FontInfo FontList::Get(const OUString& rName, const OUString& rStyleName) const
579 : {
580 16 : ImplFontListNameInfo* pData = ImplFindByName( rName );
581 16 : ImplFontListFontInfo* pFontInfo = NULL;
582 16 : ImplFontListFontInfo* pFontNameInfo = NULL;
583 16 : if ( pData )
584 : {
585 0 : ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
586 0 : pFontNameInfo = pSearchInfo;
587 0 : pSearchInfo = pData->mpFirst;
588 0 : while ( pSearchInfo )
589 : {
590 0 : if (rStyleName.equalsIgnoreAsciiCase(GetStyleName(*pSearchInfo)))
591 : {
592 0 : pFontInfo = pSearchInfo;
593 0 : break;
594 : }
595 :
596 0 : pSearchInfo = pSearchInfo->mpNext;
597 : }
598 : }
599 :
600 : // reproduce attributes if data could not be found
601 16 : vcl::FontInfo aInfo;
602 16 : if ( !pFontInfo )
603 : {
604 16 : FontWeight eWeight = WEIGHT_DONTKNOW;
605 16 : FontItalic eItalic = ITALIC_NONE;
606 :
607 16 : if ( rStyleName == maNormal )
608 : {
609 16 : eItalic = ITALIC_NONE;
610 16 : eWeight = WEIGHT_NORMAL;
611 : }
612 0 : else if ( rStyleName == maNormalItalic )
613 : {
614 0 : eItalic = ITALIC_NORMAL;
615 0 : eWeight = WEIGHT_NORMAL;
616 : }
617 0 : else if ( rStyleName == maBold )
618 : {
619 0 : eItalic = ITALIC_NONE;
620 0 : eWeight = WEIGHT_BOLD;
621 : }
622 0 : else if ( rStyleName == maBoldItalic )
623 : {
624 0 : eItalic = ITALIC_NORMAL;
625 0 : eWeight = WEIGHT_BOLD;
626 : }
627 0 : else if ( rStyleName == maLight )
628 : {
629 0 : eItalic = ITALIC_NONE;
630 0 : eWeight = WEIGHT_LIGHT;
631 : }
632 0 : else if ( rStyleName == maLightItalic )
633 : {
634 0 : eItalic = ITALIC_NORMAL;
635 0 : eWeight = WEIGHT_LIGHT;
636 : }
637 0 : else if ( rStyleName == maBlack )
638 : {
639 0 : eItalic = ITALIC_NONE;
640 0 : eWeight = WEIGHT_BLACK;
641 : }
642 0 : else if ( rStyleName == maBlackItalic )
643 : {
644 0 : eItalic = ITALIC_NORMAL;
645 0 : eWeight = WEIGHT_BLACK;
646 : }
647 16 : aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
648 : }
649 : else
650 0 : aInfo = *pFontInfo;
651 :
652 : // set Fontname to keep FontAlias
653 16 : aInfo.SetName( rName );
654 16 : aInfo.SetStyleName( rStyleName );
655 :
656 16 : return aInfo;
657 : }
658 :
659 19089 : vcl::FontInfo FontList::Get(const OUString& rName,
660 : FontWeight eWeight, FontItalic eItalic) const
661 : {
662 19089 : ImplFontListNameInfo* pData = ImplFindByName( rName );
663 19089 : ImplFontListFontInfo* pFontInfo = NULL;
664 19089 : ImplFontListFontInfo* pFontNameInfo = NULL;
665 19089 : if ( pData )
666 : {
667 12 : ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
668 12 : pFontNameInfo = pSearchInfo;
669 24 : while ( pSearchInfo )
670 : {
671 24 : if ( (eWeight == pSearchInfo->GetWeight()) &&
672 12 : (eItalic == pSearchInfo->GetItalic()) )
673 : {
674 12 : pFontInfo = pSearchInfo;
675 12 : break;
676 : }
677 :
678 0 : pSearchInfo = pSearchInfo->mpNext;
679 : }
680 : }
681 :
682 : // reproduce attributes if data could not be found
683 19089 : vcl::FontInfo aInfo;
684 19089 : if ( !pFontInfo )
685 19077 : aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
686 : else
687 12 : aInfo = *pFontInfo;
688 :
689 : // set Fontname to keep FontAlias
690 19089 : aInfo.SetName( rName );
691 :
692 19089 : return aInfo;
693 : }
694 :
695 983 : bool FontList::IsAvailable(const OUString& rName) const
696 : {
697 983 : return (ImplFindByName( rName ) != 0);
698 : }
699 :
700 473258 : const vcl::FontInfo& FontList::GetFontName( sal_uInt16 nFont ) const
701 : {
702 : DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
703 :
704 473258 : return *(maEntries[nFont].mpFirst);
705 : }
706 :
707 8 : sal_Handle FontList::GetFirstFontInfo(const OUString& rName) const
708 : {
709 8 : ImplFontListNameInfo* pData = ImplFindByName( rName );
710 8 : if ( !pData )
711 7 : return nullptr;
712 : else
713 1 : return static_cast<sal_Handle>(pData->mpFirst);
714 : }
715 :
716 0 : sal_Handle FontList::GetNextFontInfo( sal_Handle hFontInfo )
717 : {
718 0 : ImplFontListFontInfo* pInfo = static_cast<ImplFontListFontInfo*>(hFontInfo);
719 0 : return static_cast<sal_Handle>(pInfo->mpNext);
720 : }
721 :
722 1 : const vcl::FontInfo& FontList::GetFontInfo( sal_Handle hFontInfo )
723 : {
724 1 : ImplFontListFontInfo* pInfo = static_cast<ImplFontListFontInfo*>(hFontInfo);
725 1 : return *pInfo;
726 : }
727 :
728 1673 : const sal_IntPtr* FontList::GetSizeAry( const vcl::FontInfo& rInfo ) const
729 : {
730 : // first delete Size-Array
731 1673 : if ( mpSizeAry )
732 : {
733 0 : delete[] const_cast<FontList*>(this)->mpSizeAry;
734 0 : const_cast<FontList*>(this)->mpSizeAry = NULL;
735 : }
736 :
737 : // use standarad sizes if no name
738 1673 : if ( rInfo.GetName().isEmpty() )
739 0 : return aStdSizeAry;
740 :
741 : // first search fontname in order to use device from the matching font
742 1673 : OutputDevice* pDevice = mpDev;
743 1673 : ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
744 1673 : if ( pData )
745 1665 : pDevice = pData->mpFirst->GetDevice();
746 :
747 1673 : int nDevSizeCount = pDevice->GetDevFontSizeCount( rInfo );
748 5019 : if ( !nDevSizeCount ||
749 1673 : (pDevice->GetDevFontSize( rInfo, 0 ).Height() == 0) )
750 1673 : return aStdSizeAry;
751 :
752 0 : MapMode aOldMapMode = pDevice->GetMapMode();
753 0 : MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
754 0 : pDevice->SetMapMode( aMap );
755 :
756 : sal_uInt16 i;
757 0 : sal_uInt16 nRealCount = 0;
758 0 : long nOldHeight = 0;
759 0 : const_cast<FontList*>(this)->mpSizeAry = new sal_IntPtr[nDevSizeCount+1];
760 0 : for ( i = 0; i < nDevSizeCount; i++ )
761 : {
762 0 : Size aSize = pDevice->GetDevFontSize( rInfo, i );
763 0 : if ( aSize.Height() != nOldHeight )
764 : {
765 0 : nOldHeight = aSize.Height();
766 0 : const_cast<FontList*>(this)->mpSizeAry[nRealCount] = nOldHeight;
767 0 : nRealCount++;
768 : }
769 : }
770 0 : const_cast<FontList*>(this)->mpSizeAry[nRealCount] = 0;
771 :
772 0 : pDevice->SetMapMode( aOldMapMode );
773 0 : return mpSizeAry;
774 : }
775 :
776 : struct ImplFSNameItem
777 : {
778 : long mnSize;
779 : const char* mszUtf8Name;
780 : };
781 :
782 : static const ImplFSNameItem aImplSimplifiedChinese[] =
783 : {
784 : { 50, "\xe5\x85\xab\xe5\x8f\xb7" },
785 : { 55, "\xe4\xb8\x83\xe5\x8f\xb7" },
786 : { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
787 : { 75, "\xe5\x85\xad\xe5\x8f\xb7" },
788 : { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
789 : { 105, "\xe4\xba\x94\xe5\x8f\xb7" },
790 : { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
791 : { 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
792 : { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
793 : { 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
794 : { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
795 : { 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
796 : { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
797 : { 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
798 : { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
799 : { 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
800 : };
801 :
802 11633 : FontSizeNames::FontSizeNames( LanguageType eLanguage )
803 : {
804 11633 : if ( eLanguage == LANGUAGE_DONTKNOW )
805 0 : eLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
806 11633 : if ( eLanguage == LANGUAGE_SYSTEM )
807 0 : eLanguage = MsLangId::getSystemUILanguage();
808 :
809 11633 : if (MsLangId::isSimplifiedChinese(eLanguage))
810 : {
811 : // equivalent for traditional chinese disabled by popular request, #i89077#
812 0 : mpArray = aImplSimplifiedChinese;
813 0 : mnElem = SAL_N_ELEMENTS(aImplSimplifiedChinese);
814 : }
815 : else
816 : {
817 11633 : mpArray = NULL;
818 11633 : mnElem = 0;
819 : }
820 11633 : }
821 :
822 4338 : long FontSizeNames::Name2Size( const OUString& rName ) const
823 : {
824 4338 : if ( mnElem )
825 : {
826 : OString aName(OUStringToOString(rName,
827 0 : RTL_TEXTENCODING_UTF8));
828 :
829 : // linear search is sufficient for this rare case
830 0 : for( long i = mnElem; --i >= 0; )
831 0 : if ( aName.equals(mpArray[i].mszUtf8Name) )
832 0 : return mpArray[i].mnSize;
833 : }
834 :
835 4338 : return 0;
836 : }
837 :
838 4636 : OUString FontSizeNames::Size2Name( long nValue ) const
839 : {
840 4636 : OUString aStr;
841 :
842 : // binary search
843 9272 : for( long lower = 0, upper = mnElem - 1; lower <= upper; )
844 : {
845 0 : long mid = (upper + lower) >> 1;
846 0 : if ( nValue == mpArray[mid].mnSize )
847 : {
848 0 : aStr = OUString( mpArray[mid].mszUtf8Name, strlen(mpArray[mid].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
849 0 : break;
850 : }
851 0 : else if ( nValue < mpArray[mid].mnSize )
852 0 : upper = mid - 1;
853 : else /* ( nValue > mpArray[mid].mnSize ) */
854 0 : lower = mid + 1;
855 : }
856 :
857 4636 : return aStr;
858 : }
859 :
860 0 : OUString FontSizeNames::GetIndexName( sal_uLong nIndex ) const
861 : {
862 0 : OUString aStr;
863 :
864 0 : if ( nIndex < mnElem )
865 0 : aStr = OUString( mpArray[nIndex].mszUtf8Name, strlen(mpArray[nIndex].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
866 :
867 0 : return aStr;
868 : }
869 :
870 0 : long FontSizeNames::GetIndexSize( sal_uLong nIndex ) const
871 : {
872 0 : if ( nIndex >= mnElem )
873 0 : return 0;
874 0 : return mpArray[nIndex].mnSize;
875 : }
876 :
877 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|