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