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