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