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