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