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