00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "OSDLTrueTypeFont.h"
00028
00029 #include "OSDLSurface.h"
00030 #include "OSDLPixel.h"
00031 #include "OSDLUtils.h"
00032
00033 #include "Ceylan.h"
00034
00035
00036 #include <list>
00037
00038
00039
00040 #ifdef OSDL_USES_CONFIG_H
00041 #include "OSDLConfig.h"
00042 #endif // OSDL_USES_CONFIG_H
00043
00044 #if OSDL_ARCH_NINTENDO_DS
00045 #include "OSDLConfigForNintendoDS.h"
00046 #endif // OSDL_ARCH_NINTENDO_DS
00047
00048
00049
00050 #if OSDL_USES_SDL_GFX
00051 #include "SDL_gfxPrimitives.h"
00052 #endif // OSDL_USES_SDL_GFX
00053
00054 #if OSDL_USES_SDL_TTF
00055 #include "SDL_ttf.h"
00056 #endif // OSDL_USES_SDL_TTF
00057
00058 #if OSDL_USES_SDL
00059 #include "SDL.h"
00060 #endif // OSDL_USES_SDL
00061
00062
00063
00064 using namespace OSDL::Video ;
00065 using namespace OSDL::Video::Pixels ;
00066 using namespace OSDL::Video::TwoDimensional ;
00067 using namespace OSDL::Video::TwoDimensional::Text ;
00068
00069
00070 using namespace Ceylan ;
00071 using namespace Ceylan::Log ;
00072 using namespace Ceylan::System ;
00073
00074
00075 using std::string ;
00076
00077
00078
00079
00080
00081 Ceylan::System::FileLocator Text::TrueTypeFont::TrueTypeFontFileLocator ;
00082
00083 string Text::TrueTypeFont::TrueTypeFontFileExtension = ".ttf" ;
00084
00085
00086 PointSize Text::TrueTypeFont::DefaultPointSize = 20 ;
00087
00088 const Ceylan::Float32 Text::TrueTypeFont::SpaceWidthFactor = 1 ;
00089
00090
00091
00092
00093 Ceylan::Uint32 TrueTypeFont::FontCounter = 0 ;
00094
00095
00096
00097
00098 TrueTypeFont::TrueTypeFont(
00099 const std::string & fontFilename,
00100 FontIndex index,
00101 bool convertToDisplay,
00102 RenderCache cacheSettings,
00103 bool preload ) :
00104 Font( convertToDisplay, cacheSettings ),
00105 Ceylan::LoadableWithContent<LowLevelTTFFont>( fontFilename ),
00106 _pointSize( DefaultPointSize )
00107 {
00108
00109 if ( preload )
00110 {
00111
00112 try
00113 {
00114
00115 load() ;
00116
00117 }
00118 catch( const Ceylan::LoadableException & e )
00119 {
00120
00121 throw FontException(
00122 "TrueTypeFont constructor failed while preloading: "
00123 + e.toString() ) ;
00124
00125 }
00126
00127 }
00128
00129 }
00130
00131
00132
00133 TrueTypeFont::~TrueTypeFont() throw()
00134 {
00135
00136 try
00137 {
00138
00139 if ( hasContent() )
00140 unload() ;
00141
00142 }
00143 catch( const Ceylan::LoadableException & e )
00144 {
00145
00146 LogPlug::error( "TrueTypeFont destructor failed while unloading: "
00147 + e.toString() ) ;
00148
00149 }
00150
00151 LogPlug::trace( "TrueTypeFont deallocated." ) ;
00152
00153
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163 bool TrueTypeFont::load()
00164 {
00165
00166 #if OSDL_ARCH_NINTENDO_DS
00167
00168 throw Ceylan::LoadableException( "TrueTypeFont::load failed: "
00169 "not supported on the Nintendo DS" ) ;
00170
00171 #else // OSDL_ARCH_NINTENDO_DS
00172
00173 #if OSDL_USES_SDL_TTF
00174
00175 if ( hasContent() )
00176 return false ;
00177
00178
00179 if ( ::TTF_WasInit() == 0 )
00180 {
00181
00182 if ( ::TTF_Init()== -1 )
00183 throw FontException(
00184 "TrueTypeFont constructor: unable to init font library: "
00185 + DescribeLastError() ) ;
00186
00187 }
00188
00189
00190
00191 try
00192 {
00193
00194
00195
00196
00197
00198 #if OSDL_DEBUG_FONT
00199
00200 LogPlug::debug( "TrueTypeFont::load: loading from file '"
00201 + _contentPath + "' for size " + Ceylan::toString( _pointSize ) ) ;
00202
00203 #endif // OSDL_DEBUG_FONT
00204
00205
00206 Ceylan::System::File & fontFile = File::Open( _contentPath ) ;
00207
00208 _content = ::TTF_OpenFontRW(
00209 & OSDL::Utils::createDataStreamFrom( fontFile ),
00210 true, _pointSize ) ;
00211
00212 }
00213 catch( const Ceylan::Exception & e )
00214 {
00215
00216 throw FontException(
00217 "TrueTypeFont constructor failed: unable to load from '"
00218 + _contentPath + "': " + e.toString() ) ;
00219
00220 }
00221
00222 if ( _content == 0 )
00223 throw FontException( "TrueTypeFont constructor: unable to open '"
00224 + _contentPath
00225 + "' with a point size of "
00226 + Ceylan::toString( _pointSize ) + " dots per inch: "
00227 + DescribeLastError() ) ;
00228
00229 _spaceWidth = static_cast<Width>( SpaceWidthFactor * getWidth( ' ' ) ) ;
00230
00231
00232 _alineaWidth = DefaultSpaceBasedAlineaWidth * _spaceWidth ;
00233
00234 FontCounter++ ;
00235
00236 return true ;
00237
00238 #else // OSDL_USES_SDL_TTF
00239
00240 throw FontException( "TrueTypeFont constructor failed: "
00241 "no SDL_ttf support available" ) ;
00242
00243 #endif // OSDL_USES_SDL_TTF
00244
00245 #endif // OSDL_ARCH_NINTENDO_DS
00246
00247 }
00248
00249
00250
00251 bool TrueTypeFont::unload()
00252 {
00253
00254 if ( ! hasContent() )
00255 return false ;
00256
00257
00258 #if OSDL_ARCH_NINTENDO_DS
00259
00260 throw Ceylan::LoadableException( "TrueTypeFont::unload failed: "
00261 "not supported on the Nintendo DS." ) ;
00262
00263 #else // OSDL_ARCH_NINTENDO_DS
00264
00265
00266 #if OSDL_USES_SDL_TTF
00267
00268 if ( _content != 0 )
00269 {
00270
00271
00272
00273 ::TTF_CloseFont( _content ) ;
00274
00275 }
00276
00277 FontCounter-- ;
00278
00279 if ( FontCounter == 0 && ::TTF_WasInit() != 0 )
00280 ::TTF_Quit() ;
00281
00282 #else // OSDL_USES_SDL_MIXER
00283
00284 throw Ceylan::LoadableException(
00285 "TrueTypeFont::unload failed: no SDL_ttf support available." ) ;
00286
00287 #endif // OSDL_USES_SDL_TTF
00288
00289
00290 #endif // OSDL_ARCH_NINTENDO_DS
00291
00292 _content = 0 ;
00293
00294 return true ;
00295
00296 }
00297
00298
00299
00300 bool TrueTypeFont::load( PointSize newPointSize )
00301 {
00302
00303 setPointSize( newPointSize ) ;
00304
00305 return load() ;
00306
00307 }
00308
00309
00310
00311 PointSize TrueTypeFont::getPointSize() const
00312 {
00313
00314 return _pointSize ;
00315
00316 }
00317
00318
00319
00320 void TrueTypeFont::setPointSize( PointSize newPointSize )
00321 {
00322
00323
00324 if ( newPointSize == _pointSize )
00325 return ;
00326
00327 _pointSize = newPointSize ;
00328
00329
00330 if ( ! hasContent() )
00331 return ;
00332
00333
00334
00335 unload() ;
00336
00337 load() ;
00338
00339 }
00340
00341
00342
00343 RenderingStyle TrueTypeFont::getRenderingStyle() const
00344 {
00345
00346 #if OSDL_USES_SDL_TTF
00347
00348 if ( ! hasContent() )
00349 throw FontException( "TrueTypeFont::getRenderingStyle failed: "
00350 "font not loaded" ) ;
00351
00352 return ::TTF_GetFontStyle( _content ) ;
00353
00354 #else // OSDL_USES_SDL_TTF
00355
00356 return 0 ;
00357
00358 #endif // OSDL_USES_SDL_TTF
00359
00360 }
00361
00362
00363
00364 void TrueTypeFont::setRenderingStyle( RenderingStyle newStyle )
00365 {
00366
00367 #if OSDL_USES_SDL_TTF
00368
00369 if ( ! hasContent() )
00370 throw FontException( "TrueTypeFont::setRenderingStyle failed: "
00371 "font not loaded" ) ;
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 if ( newStyle != getRenderingStyle() )
00382 ::TTF_SetFontStyle( _content, newStyle ) ;
00383
00384 #else // OSDL_USES_SDL_TTF
00385
00386 throw FontException( "TrueTypeFont::setRenderingStyle failed: "
00387 "no SDL_ttf support available" ) ;
00388
00389 #endif // OSDL_USES_SDL_TTF
00390
00391 }
00392
00393
00394
00395 Width TrueTypeFont::getWidth( Ceylan::Latin1Char character ) const
00396 {
00397
00398 #if OSDL_USES_SDL_TTF
00399
00400 if ( ! hasContent() )
00401 throw FontException( "TrueTypeFont::getWidth failed: "
00402 "font not loaded" ) ;
00403
00404
00405
00406
00407
00408
00409
00410 if ( character == ' ' )
00411 return getAdvance( ' ' ) ;
00412
00413 int minX, maxX ;
00414
00415 if ( ::TTF_GlyphMetrics( _content,
00416 Ceylan::UnicodeString::ConvertFromLatin1( character),
00417 & minX, & maxX, 0, 0, 0 ) != 0 )
00418 throw FontException( "TrueTypeFont::getWidth: "
00419 + DescribeLastError() ) ;
00420
00421 return static_cast<Width>( maxX - minX ) ;
00422
00423 #else // OSDL_USES_SDL_TTF
00424
00425 throw FontException( "TrueTypeFont::getWidth failed: "
00426 "no SDL_ttf support available" ) ;
00427
00428 #endif // OSDL_USES_SDL_TTF
00429
00430 }
00431
00432
00433
00434 SignedWidth TrueTypeFont::getWidthOffset( Ceylan::Latin1Char character ) const
00435 {
00436
00437 #if OSDL_USES_SDL_TTF
00438
00439 if ( ! hasContent() )
00440 throw FontException( "TrueTypeFont::getWidthOffset failed: "
00441 "font not loaded" ) ;
00442
00443 int minX ;
00444
00445 if ( ::TTF_GlyphMetrics( _content,
00446 Ceylan::UnicodeString::ConvertFromLatin1( character),
00447 & minX, 0, 0, 0, 0 ) != 0 )
00448 throw FontException( "TrueTypeFont::getWidthOffset: "
00449 + DescribeLastError() ) ;
00450
00451 return static_cast<SignedWidth>( minX ) ;
00452
00453 #else // OSDL_USES_SDL_TTF
00454
00455 throw FontException( "TrueTypeFont::getWidthOffset failed: "
00456 "no SDL_ttf support available" ) ;
00457
00458 #endif // OSDL_USES_SDL_TTF
00459
00460 }
00461
00462
00463
00464 SignedHeight TrueTypeFont::getHeightAboveBaseline(
00465 Ceylan::Latin1Char character ) const
00466 {
00467
00468 #if OSDL_USES_SDL_TTF
00469
00470 if ( ! hasContent() )
00471 throw FontException( "TrueTypeFont::getHeightAboveBaseline failed: "
00472 "font not loaded" ) ;
00473
00474 int maxY ;
00475
00476 if ( ::TTF_GlyphMetrics( _content,
00477 Ceylan::UnicodeString::ConvertFromLatin1( character),
00478 0, 0, 0, & maxY, 0 ) != 0 )
00479 throw FontException( "TrueTypeFont::getHeightAboveBaseline: "
00480 + DescribeLastError() ) ;
00481
00482 return static_cast<SignedHeight>( maxY ) ;
00483
00484 #else // OSDL_USES_SDL_TTF
00485
00486 throw FontException( "TrueTypeFont::getHeightAboveBaseline failed: "
00487 "no SDL_ttf support available" ) ;
00488
00489 #endif // OSDL_USES_SDL_TTF
00490
00491 }
00492
00493
00494
00495 OSDL::Video::SignedLength TrueTypeFont::getAdvance(
00496 Ceylan::Latin1Char character ) const
00497 {
00498
00499 #if OSDL_USES_SDL_TTF
00500
00501 if ( ! hasContent() )
00502 throw FontException( "TrueTypeFont::getAdvance failed: "
00503 "font not loaded" ) ;
00504
00505 int advance ;
00506
00507 if ( ::TTF_GlyphMetrics( _content,
00508 Ceylan::UnicodeString::ConvertFromLatin1( character),
00509 0, 0, 0, 0, & advance ) != 0 )
00510 throw FontException( "TrueTypeFont::getAdvance: "
00511 + DescribeLastError() ) ;
00512
00513 return static_cast<SignedLength>( advance ) ;
00514
00515 #else // OSDL_USES_SDL_TTF
00516
00517 throw FontException( "TrueTypeFont::getAdvance failed: "
00518 "no SDL_ttf support available" ) ;
00519
00520 #endif // OSDL_USES_SDL_TTF
00521
00522 }
00523
00524
00525
00526 Text::Height TrueTypeFont::getHeight() const
00527 {
00528
00529 #if OSDL_USES_SDL_TTF
00530
00531 if ( ! hasContent() )
00532 throw FontException( "TrueTypeFont::getHeight failed: "
00533 "font not loaded" ) ;
00534
00535 return ::TTF_FontHeight( _content ) ;
00536
00537 #else // OSDL_USES_SDL_TTF
00538
00539 return 0 ;
00540
00541 #endif // OSDL_USES_SDL_TTF
00542
00543 }
00544
00545
00546
00547 Text::SignedHeight TrueTypeFont::getAscent() const
00548 {
00549
00550 #if OSDL_USES_SDL_TTF
00551
00552 if ( ! hasContent() )
00553 throw FontException( "TrueTypeFont::getAscent failed: "
00554 "font not loaded" ) ;
00555
00556 return ::TTF_FontAscent( _content ) ;
00557
00558 #else // OSDL_USES_SDL_TTF
00559
00560 return 0 ;
00561
00562 #endif // OSDL_USES_SDL_TTF
00563
00564 }
00565
00566
00567
00568 Text::SignedHeight TrueTypeFont::getDescent() const
00569 {
00570
00571 #if OSDL_USES_SDL_TTF
00572
00573 if ( ! hasContent() )
00574 throw FontException( "TrueTypeFont::getDescent failed: "
00575 "font not loaded" ) ;
00576
00577 return ::TTF_FontDescent( _content ) ;
00578
00579 #else // OSDL_USES_SDL_TTF
00580
00581 return 0 ;
00582
00583 #endif // OSDL_USES_SDL_TTF
00584
00585 }
00586
00587
00588
00589 Text::Height TrueTypeFont::getLineSkip() const
00590 {
00591
00592 #if OSDL_USES_SDL_TTF
00593
00594 if ( ! hasContent() )
00595 throw FontException( "TrueTypeFont::getLineSkip failed: "
00596 "font not loaded" ) ;
00597
00598 return ::TTF_FontLineSkip( _content ) ;
00599
00600 #else // OSDL_USES_SDL_TTF
00601
00602 return 0 ;
00603
00604 #endif // OSDL_USES_SDL_TTF
00605
00606 }
00607
00608
00609 Ceylan::Uint16 TrueTypeFont::getFacesCount() const
00610 {
00611
00612 #if OSDL_USES_SDL_TTF
00613
00614 if ( ! hasContent() )
00615 throw FontException( "TrueTypeFont::getFacesCount failed: "
00616 "font not loaded" ) ;
00617
00618 return static_cast<Ceylan::Uint16>( ::TTF_FontFaces( _content ) ) ;
00619
00620 #else // OSDL_USES_SDL_TTF
00621
00622 return 0 ;
00623
00624 #endif // OSDL_USES_SDL_TTF
00625
00626 }
00627
00628
00629
00630 bool TrueTypeFont::isFixedWidth() const
00631 {
00632
00633 #if OSDL_USES_SDL_TTF
00634
00635 if ( ! hasContent() )
00636 throw FontException( "TrueTypeFont::isFixedWidth failed: "
00637 "font not loaded" ) ;
00638
00639 return ( ::TTF_FontFaceIsFixedWidth( _content ) > 0 ) ;
00640
00641 #else // OSDL_USES_SDL_TTF
00642
00643 return 0 ;
00644
00645 #endif // OSDL_USES_SDL_TTF
00646
00647 }
00648
00649
00650
00651 string TrueTypeFont::getFaceFamilyName() const
00652 {
00653
00654 #if OSDL_USES_SDL_TTF
00655
00656 if ( ! hasContent() )
00657 throw FontException( "TrueTypeFont::getFaceFamilyName failed: "
00658 "font not loaded" ) ;
00659
00660 return ::TTF_FontFaceFamilyName( _content ) ;
00661
00662 #else // OSDL_USES_SDL_TTF
00663
00664 return 0 ;
00665
00666 #endif // OSDL_USES_SDL_TTF
00667
00668 }
00669
00670
00671
00672 string TrueTypeFont::getFaceStyleName() const
00673 {
00674
00675 #if OSDL_USES_SDL_TTF
00676
00677 if ( ! hasContent() )
00678 throw FontException( "TrueTypeFont::getFaceStyleName failed: "
00679 "font not loaded" ) ;
00680
00681 return ::TTF_FontFaceStyleName( _content ) ;
00682
00683 #else // OSDL_USES_SDL_TTF
00684
00685 return 0 ;
00686
00687 #endif // OSDL_USES_SDL_TTF
00688
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698 UprightRectangle & TrueTypeFont::getBoundingBoxFor(
00699 Ceylan::Unicode glyph, SignedLength & advance ) const
00700 {
00701
00702 #if OSDL_USES_SDL_TTF
00703
00704 if ( ! hasContent() )
00705 throw FontException( "TrueTypeFont::getBoundingBoxFor failed: "
00706 "font not loaded" ) ;
00707
00708 int minX, maxX, minY, maxY, intAdvance ;
00709
00710 if ( ::TTF_GlyphMetrics( _content, glyph, & minX, & maxX,
00711 & minY, & maxY, & intAdvance ) != 0 )
00712 throw FontException( "TrueTypeFont::getClippingBoxFor (glyph): "
00713 + DescribeLastError() ) ;
00714
00715 advance = static_cast<SignedLength>( intAdvance ) ;
00716
00717 return * new UprightRectangle(
00718 static_cast<Coordinate>( minX ),
00719 static_cast<Coordinate>( maxY ),
00720 static_cast<Length>( maxX - minX ),
00721 static_cast<Length>( maxY - minY ) ) ;
00722
00723 #else // OSDL_USES_SDL_TTF
00724
00725 throw FontException( "TrueTypeFont::getBoundingBoxFor failed: "
00726 "no SDL_ttf support available" ) ;
00727
00728 #endif // OSDL_USES_SDL_TTF
00729
00730 }
00731
00732
00733
00734 UprightRectangle & TrueTypeFont::getBoundingBoxFor( const std::string & text )
00735 const
00736 {
00737
00738 #if OSDL_USES_SDL_TTF
00739
00740 if ( ! hasContent() )
00741 throw FontException( "TrueTypeFont::getBoundingBoxFor failed: "
00742 "font not loaded" ) ;
00743
00744 int width, height ;
00745
00746 if ( ::TTF_SizeText( _content, text.c_str(), & width, & height ) != 0 )
00747 throw FontException(
00748 "TrueTypeFont::getBoundingBoxFor (Latin-1 string): "
00749 + DescribeLastError() ) ;
00750
00751 return * new UprightRectangle( 0, 0, static_cast<Length>( width ),
00752 static_cast<Length>( height ) ) ;
00753
00754 #else // OSDL_USES_SDL_TTF
00755
00756 throw FontException( "TrueTypeFont::getBoundingBoxFor failed: "
00757 "no SDL_ttf support available" ) ;
00758
00759 #endif // OSDL_USES_SDL_TTF
00760
00761 }
00762
00763
00764
00765 UprightRectangle & TrueTypeFont::getBoundingBoxForUTF8(
00766 const std::string & text ) const
00767 {
00768
00769 #if OSDL_USES_SDL_TTF
00770
00771 if ( ! hasContent() )
00772 throw FontException( "TrueTypeFont::getBoundingBoxForUTF8 failed: "
00773 "font not loaded" ) ;
00774
00775 int width, height ;
00776
00777 if ( ::TTF_SizeUTF8( _content, text.c_str(), & width, & height ) != 0 )
00778 throw FontException(
00779 "TrueTypeFont::getBoundingBoxFor (UTF-8 string): "
00780 + DescribeLastError() ) ;
00781
00782 return * new UprightRectangle( 0, 0, static_cast<Length>( width ),
00783 static_cast<Length>( height ) ) ;
00784
00785 #else // OSDL_USES_SDL_TTF
00786
00787 throw FontException( "TrueTypeFont::getBoundingBoxForUTF8 failed: "
00788 "no SDL_ttf support available" ) ;
00789
00790 #endif // OSDL_USES_SDL_TTF
00791
00792 }
00793
00794
00795
00796 UprightRectangle & TrueTypeFont::getBoundingBoxForUnicode(
00797 const Ceylan::Unicode * text ) const
00798 {
00799
00800 #if OSDL_USES_SDL_TTF
00801
00802 if ( ! hasContent() )
00803 throw FontException( "TrueTypeFont::getBoundingBoxForUnicode failed: "
00804 "font not loaded" ) ;
00805
00806 if ( text == 0 )
00807 throw FontException( "TrueTypeFont::getBoundingBoxForUnicode: "
00808 "null pointer for Unicode string." ) ;
00809
00810 int width, height ;
00811
00812 if ( ::TTF_SizeUNICODE( _content, text, & width, & height ) != 0 )
00813 throw FontException(
00814 "TrueTypeFont::getBoundingBoxFor (Unicode string): "
00815 + DescribeLastError() ) ;
00816
00817 return * new UprightRectangle( 0, 0, static_cast<Length>( width ),
00818 static_cast<Length>( height ) ) ;
00819
00820 #else // OSDL_USES_SDL_TTF
00821
00822 throw FontException( "TrueTypeFont::getBoundingBoxForUnicode failed: "
00823 "no SDL_ttf support available" ) ;
00824
00825 #endif // OSDL_USES_SDL_TTF
00826
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836 OSDL::Video::Surface & TrueTypeFont::renderLatin1Glyph(
00837 Ceylan::Latin1Char character,
00838 RenderQuality quality,
00839 Pixels::ColorDefinition glyphColor )
00840 {
00841
00842 return renderUnicodeGlyph(
00843 Ceylan::UnicodeString::ConvertFromLatin1( character ),
00844 quality, glyphColor ) ;
00845
00846 }
00847
00848
00849
00850 void TrueTypeFont::blitLatin1Glyph(
00851 Surface & targetSurface, Coordinate x, Coordinate y,
00852 Ceylan::Latin1Char character, RenderQuality quality,
00853 Pixels::ColorDefinition glyphColor )
00854 {
00855
00856 #if OSDL_DEBUG_FONT
00857
00858 LogPlug::debug( "TrueTypeFont::blitLatin1Glyph: "
00859 "rendering Latin-1 character '"
00860 + Ceylan::toString( character ) + "', whose Unicode is '"
00861 + Ceylan::toString(
00862 Ceylan::UnicodeString::ConvertFromLatin1( character ) )
00863 + "'." ) ;
00864
00865
00866
00867
00868
00869
00870
00871 #endif // OSDL_DEBUG_FONT
00872
00873
00874
00875 Surface & res = renderUnicodeGlyph(
00876 Ceylan::UnicodeString::ConvertFromLatin1( character ),
00877 quality, glyphColor ) ;
00878
00879 res.blitTo( targetSurface, x, y ) ;
00880
00881 delete & res ;
00882
00883 }
00884
00885
00886
00887 OSDL::Video::Surface & TrueTypeFont::renderUnicodeGlyph(
00888 Ceylan::Unicode character,
00889 RenderQuality quality,
00890 Pixels::ColorDefinition glyphColor )
00891 {
00892
00893
00894
00895 if ( _cacheSettings == GlyphCached )
00896 {
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 CharColorQualityKey renderKey(
00907 static_cast<Ceylan::Latin1Char>( character ),
00908 glyphColor, quality ) ;
00909
00910 SmartResource * res = _glyphCache->getClone( renderKey ) ;
00911
00912 if ( res != 0 )
00913 {
00914
00915 Surface * returned = dynamic_cast<Surface *>( res ) ;
00916
00917 #if OSDL_DEBUG_FONT
00918
00919 LogPlug::debug( "TrueTypeFont::renderUnicodeGlyph: cache hit, "
00920 "returning clone of prerendered glyph." ) ;
00921
00922 if ( returned == 0 )
00923 Ceylan::emergencyShutdown( "TrueTypeFont::renderUnicodeGlyph: "
00924 "clone is not a Surface." ) ;
00925
00926 #endif // OSDL_DEBUG_FONT
00927
00928 return * returned ;
00929
00930 }
00931
00932 #if OSDL_DEBUG_FONT
00933
00934 LogPlug::debug( "TrueTypeFont::renderUnicodeGlyph: "
00935 "cache miss, creating new glyph rendering for character '"
00936 + Ceylan::toString( character ) + "'." ) ;
00937
00938 #endif // OSDL_DEBUG_FONT
00939
00940
00941 Surface & newSurface = basicRenderUnicodeGlyph( character, quality,
00942 glyphColor ) ;
00943
00944
00945 _glyphCache->scanForAddition( renderKey, newSurface ) ;
00946
00947
00948 return newSurface ;
00949
00950 }
00951
00952
00953
00954
00955
00956 return basicRenderUnicodeGlyph( character, quality, glyphColor ) ;
00957
00958 }
00959
00960
00961
00962
00963 OSDL::Video::Surface & TrueTypeFont::renderLatin1Text(
00964 const std::string & text,
00965 RenderQuality quality, Pixels::ColorDefinition textColor )
00966 {
00967
00968 #if OSDL_USES_SDL_TTF
00969
00970 if ( ! hasContent() )
00971 throw FontException( "TrueTypeFont::renderLatin1Text failed: "
00972 "font not loaded" ) ;
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991 return Font::renderLatin1Text( text, quality, textColor ) ;
00992
00993
00994
00995
00996
00997
00998
00999
01000 SDL_Surface * textSurface ;
01001 Surface * res ;
01002
01003 switch( quality )
01004 {
01005
01006 case Solid:
01007 textSurface = ::TTF_RenderText_Solid( _content,
01008 text.c_str(), textColor ) ;
01009 if ( textSurface == 0 )
01010 throw FontException(
01011 "TrueTypeFont::renderLatin1Text (solid): "
01012 "unable to render text '" + text
01013 + "': " + DescribeLastError() ) ;
01014 res = new Surface( * textSurface,
01015 Surface::BackBuffer ) ;
01016
01017 break ;
01018
01019
01020 case Shaded:
01021 textSurface = ::TTF_RenderText_Shaded( _content,
01022 text.c_str(), textColor, _backgroundColor ) ;
01023 if ( textSurface == 0 )
01024 throw FontException(
01025 "TrueTypeFont::renderLatin1Text (shaded): "
01026 "unable to render text '" + text
01027 + "': " + DescribeLastError() ) ;
01028
01029
01030
01031
01032
01033
01034
01035 ColorMask redMask, greenMask, blueMask ;
01036 Pixels::getRecommendedColorMasks( redMask, greenMask, blueMask ) ;
01037
01038 res = new Surface( Surface::Hardware | Surface::ColorkeyBlit,
01039 textSurface->w, textSurface->h, 32,
01040 redMask, greenMask, blueMask, 0 ) ;
01041
01042
01043 Pixels::ColorDefinition colorKey ;
01044
01045 if ( Pixels::areEqual( textColor, Pixels::Black,
01046 false ) )
01047 {
01048 colorKey = Pixels::White ;
01049 res->fill( colorKey ) ;
01050 }
01051 else
01052 {
01053 colorKey = Pixels::Black ;
01054
01055
01056
01057
01058
01059 }
01060
01061 try
01062 {
01063 res->setColorKey(
01064 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01065 Pixels::convertColorDefinitionToPixelColor(
01066 res->getPixelFormat(), colorKey ) ) ;
01067 }
01068 catch( const Video::VideoException & e )
01069 {
01070 throw FontException(
01071 "TrueTypeFont::renderLatin1Text (shaded): "
01072 "color keying failed: " + e.toString() ) ;
01073 }
01074 SDL_BlitSurface( textSurface, 0, & res->getSDLSurface(), 0 ) ;
01075 break ;
01076
01077
01078 case Blended:
01079 textSurface = ::TTF_RenderText_Blended( _content,
01080 text.c_str(), textColor ) ;
01081 if ( textSurface == 0 )
01082 throw FontException(
01083 "TrueTypeFont::renderLatin1Text (blended): "
01084 "unable to render text '" + text
01085 + "': " + DescribeLastError() ) ;
01086
01087 res = new Surface( * textSurface,
01088 Surface::BackBuffer ) ;
01089
01090
01091 #ifdef OSDL_ADDS_COLOR_KEY
01092
01093
01094
01095
01096
01097
01098
01099
01100 Pixels::ColorDefinition colorKey ;
01101
01102 if ( Pixels::areEqual( textColor, Pixels::Black,
01103 false ) )
01104 {
01105 colorKey = Pixels::White ;
01106 res->fill( colorKey ) ;
01107 }
01108 else
01109 {
01110 colorKey = Pixels::Black ;
01111
01112
01113
01114
01115
01116
01117 }
01118
01119 try
01120 {
01121 res->setColorKey(
01122 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01123 Pixels::convertColorDefinitionToPixelColor(
01124 res->getPixelFormat(), colorKey ) ) ;
01125 }
01126 catch( const Video::VideoException & e )
01127 {
01128 throw FontException(
01129 "TrueTypeFont::renderLatin1Text (blended): "
01130 "color keying failed: " + e.toString() ) ;
01131 }
01132
01133 #endif // OSDL_ADDS_COLOR_KEY
01134
01135 break ;
01136
01137
01138 default:
01139 throw FontException( "TrueTypeFont::renderLatin1Text: "
01140 "unknown quality requested: "
01141 + Ceylan::toString( quality ) + "." ) ;
01142 break ;
01143
01144 }
01145
01146
01147 if ( _convertToDisplay )
01148 {
01149
01150
01151
01152
01153
01154
01155
01156
01157 if ( quality == Blended )
01158 res->convertToDisplay( true ) ;
01159 else
01160 res->convertToDisplay( false ) ;
01161
01162 }
01163
01164 return * res ;
01165
01166 #else // OSDL_USES_SDL_TTF
01167
01168 throw FontException( "TrueTypeFont::renderLatin1Text failed: "
01169 "no SDL_ttf support available" ) ;
01170
01171 #endif // OSDL_USES_SDL_TTF
01172
01173 }
01174
01175
01176
01177 OSDL::Video::Surface & TrueTypeFont::renderUTF8Text(
01178 const std::string & text,
01179 RenderQuality quality,
01180 Pixels::ColorDefinition textColor )
01181 {
01182
01183 #if OSDL_USES_SDL_TTF
01184
01185 if ( ! hasContent() )
01186 throw FontException( "TrueTypeFont::renderUTF8Text failed: "
01187 "font not loaded" ) ;
01188
01189 SDL_Surface * textSurface ;
01190 Surface * res ;
01191
01192 switch( quality )
01193 {
01194
01195
01196 case Solid:
01197 textSurface = ::TTF_RenderUTF8_Solid( _content, text.c_str(),
01198 textColor ) ;
01199
01200 if ( textSurface == 0 )
01201 throw FontException( "TrueTypeFont::renderUTF8Text (solid): "
01202 "unable to render text '" + text
01203 + "': " + DescribeLastError() ) ;
01204
01205 res = new Surface( * textSurface,
01206 Surface::BackBuffer ) ;
01207 break ;
01208
01209
01210 case Shaded:
01211 textSurface = ::TTF_RenderUTF8_Shaded( _content, text.c_str(),
01212 textColor, _backgroundColor ) ;
01213
01214 if ( textSurface == 0 )
01215 throw FontException( "TrueTypeFont::renderUTF8Text (shaded): "
01216 "unable to render text '" + text
01217 + "': " + DescribeLastError() ) ;
01218
01219
01220
01221
01222
01223
01224
01225 ColorMask redMask, greenMask, blueMask ;
01226 Pixels::getRecommendedColorMasks( redMask, greenMask, blueMask ) ;
01227
01228 res = new Surface( Surface::Hardware | Surface::ColorkeyBlit,
01229 textSurface->w, textSurface->h, 32,
01230 redMask, greenMask, blueMask, 0 ) ;
01231
01232
01233 Pixels::ColorDefinition colorKey ;
01234
01235 if ( Pixels::areEqual( textColor, Pixels::Black,
01236 false ) )
01237 {
01238
01239 colorKey = Pixels::White ;
01240 res->fill( colorKey ) ;
01241
01242 }
01243 else
01244 {
01245
01246 colorKey = Pixels::Black ;
01247
01248
01249
01250
01251
01252
01253 }
01254
01255 try
01256 {
01257
01258 res->setColorKey(
01259 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01260 Pixels::convertColorDefinitionToPixelColor(
01261 res->getPixelFormat(), colorKey ) ) ;
01262
01263 }
01264 catch( const Video::VideoException & e )
01265 {
01266 throw FontException( "TrueTypeFont::renderUTF8Text (shaded): "
01267 "color keying failed: " + e.toString() ) ;
01268 }
01269
01270 SDL_BlitSurface( textSurface, 0, & res->getSDLSurface(), 0 ) ;
01271 break ;
01272
01273
01274 case Blended:
01275 textSurface = ::TTF_RenderUTF8_Blended( _content, text.c_str(),
01276 textColor ) ;
01277
01278 if ( textSurface == 0 )
01279 throw FontException(
01280 "TrueTypeFont::renderUTF8Text (blended): "
01281 "unable to render text '" + text
01282 + "': " + DescribeLastError() ) ;
01283
01284 res = new Surface( * textSurface,
01285 Surface::BackBuffer ) ;
01286
01287
01288
01289 #ifdef OSDL_ADDS_COLOR_KEY
01290
01291
01292
01293
01294
01295
01296
01297
01298 Pixels::ColorDefinition colorKey ;
01299
01300 if ( Pixels::areEqual( textColor, Pixels::Black,
01301 false ) )
01302 {
01303
01304 colorKey = Pixels::White ;
01305 res->fill( colorKey ) ;
01306
01307 }
01308 else
01309 {
01310
01311 colorKey = Pixels::Black ;
01312
01313
01314
01315
01316
01317 }
01318
01319 try
01320 {
01321 res->setColorKey(
01322 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01323 Pixels::convertColorDefinitionToPixelColor(
01324 res->getPixelFormat(), colorKey ) ) ;
01325 }
01326 catch( const Video::VideoException & e )
01327 {
01328
01329 throw FontException( "TrueTypeFont::renderUTF8Text (blended): "
01330 "color keying failed: " + e.toString() ) ;
01331
01332 }
01333
01334 #endif // OSDL_ADDS_COLOR_KEY
01335
01336 break ;
01337
01338
01339 default:
01340 throw FontException( "TrueTypeFont::renderUTF8Text: "
01341 "unknown quality requested: "
01342 + Ceylan::toString( quality ) + "." ) ;
01343 break ;
01344
01345 }
01346
01347
01348 if ( _convertToDisplay )
01349 {
01350
01351
01352
01353
01354
01355
01356
01357
01358 if ( quality == Blended )
01359 res->convertToDisplay( true ) ;
01360 else
01361 res->convertToDisplay( false ) ;
01362
01363 }
01364
01365 return * res ;
01366
01367 #else // OSDL_USES_SDL_TTF
01368
01369 throw FontException( "TrueTypeFont::renderUTF8Text failed: "
01370 "no SDL_ttf support available" ) ;
01371
01372 #endif // OSDL_USES_SDL_TTF
01373
01374 }
01375
01376
01377
01378 OSDL::Video::Surface & TrueTypeFont::renderUnicodeText(
01379 const Ceylan::Unicode * text,
01380 RenderQuality quality,
01381 Pixels::ColorDefinition textColor )
01382 {
01383
01384 #if OSDL_USES_SDL_TTF
01385
01386 if ( ! hasContent() )
01387 throw FontException( "TrueTypeFont::renderUnicodeText failed: "
01388 "font not loaded" ) ;
01389
01390 if ( text == 0 )
01391 throw FontException(
01392 "TrueTypeFont::renderUnicode: null pointer for Unicode string." ) ;
01393
01394 SDL_Surface * textSurface ;
01395 Surface * res ;
01396
01397 switch( quality )
01398 {
01399
01400 case Solid:
01401 textSurface = ::TTF_RenderUNICODE_Solid( _content, text,
01402 textColor ) ;
01403
01404 if ( textSurface == 0 )
01405 throw FontException(
01406 "TrueTypeFont::renderUnicodeText (solid): "
01407 "unable to render text: " + DescribeLastError() ) ;
01408 res = new Surface( * textSurface,
01409 Surface::BackBuffer ) ;
01410 break ;
01411
01412
01413 case Shaded:
01414 textSurface = ::TTF_RenderUNICODE_Shaded( _content, text,
01415 textColor, _backgroundColor ) ;
01416
01417 if ( textSurface == 0 )
01418 throw FontException(
01419 "TrueTypeFont::renderUnicodeText (shaded): "
01420 "unable to render text: " + DescribeLastError() ) ;
01421
01422
01423
01424
01425
01426
01427
01428 ColorMask redMask, greenMask, blueMask ;
01429 Pixels::getRecommendedColorMasks( redMask, greenMask, blueMask ) ;
01430
01431 res = new Surface( Surface::Hardware | Surface::ColorkeyBlit,
01432 textSurface->w, textSurface->h, 32,
01433 redMask, greenMask, blueMask, 0 ) ;
01434
01435
01436 Pixels::ColorDefinition colorKey ;
01437
01438 if ( Pixels::areEqual( textColor, Pixels::Black,
01439 false ) )
01440 {
01441
01442 colorKey = Pixels::White ;
01443 res->fill( colorKey ) ;
01444
01445 }
01446 else
01447 {
01448
01449 colorKey = Pixels::Black ;
01450
01451
01452
01453
01454
01455
01456 }
01457
01458 try
01459 {
01460 res->setColorKey(
01461 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01462 Pixels::convertColorDefinitionToPixelColor(
01463 res->getPixelFormat(), colorKey ) ) ;
01464 }
01465 catch( const Video::VideoException & e )
01466 {
01467 throw FontException(
01468 "TrueTypeFont::renderUnicodeText (shaded): "
01469 "color keying failed: " + e.toString() ) ;
01470 }
01471 SDL_BlitSurface( textSurface, 0, & res->getSDLSurface(), 0 ) ;
01472 break ;
01473
01474
01475 case Blended:
01476 textSurface = ::TTF_RenderUNICODE_Blended( _content, text,
01477 textColor ) ;
01478
01479 if ( textSurface == 0 )
01480 throw FontException(
01481 "TrueTypeFont::renderUnicodeText (blended): "
01482 "unable to render text: " + DescribeLastError() ) ;
01483
01484 res = new Surface( * textSurface,
01485 Surface::BackBuffer ) ;
01486
01487
01488
01489 #ifdef OSDL_ADDS_COLOR_KEY
01490
01491
01492
01493
01494
01495
01496
01497
01498 Pixels::ColorDefinition colorKey ;
01499
01500 if ( Pixels::areEqual( textColor, Pixels::Black,
01501 false ) )
01502 {
01503
01504 colorKey = Pixels::White ;
01505 res->fill( colorKey ) ;
01506
01507 }
01508 else
01509 {
01510
01511 colorKey = Pixels::Black ;
01512
01513
01514
01515
01516
01517
01518 }
01519
01520
01521
01522
01523
01524
01525
01526 try
01527 {
01528
01529 res->setColorKey(
01530 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01531 Pixels::convertColorDefinitionToPixelColor(
01532 res->getPixelFormat(), colorKey ) ) ;
01533
01534 }
01535 catch( const Video::VideoException & e )
01536 {
01537 throw FontException(
01538 "TrueTypeFont::renderUnicodeText (blended): "
01539 "color keying failed: " + e.toString() ) ;
01540 }
01541
01542 #endif // OSDL_ADDS_COLOR_KEY
01543
01544 break ;
01545
01546
01547 default:
01548 throw FontException( "TrueTypeFont::renderUnicodeText: "
01549 "unknown quality requested: "
01550 + Ceylan::toString( quality ) + "." ) ;
01551 break ;
01552
01553 }
01554
01555
01556 if ( _convertToDisplay )
01557 {
01558
01559
01560
01561
01562
01563
01564
01565
01566 if ( quality == Blended )
01567 res->convertToDisplay( true ) ;
01568 else
01569 res->convertToDisplay( false ) ;
01570
01571 }
01572
01573 return * res ;
01574
01575 #else // OSDL_USES_SDL_TTF
01576
01577 throw FontException( "TrueTypeFont::renderUnicodeText failed: "
01578 "no SDL_ttf support available" ) ;
01579
01580 #endif // OSDL_USES_SDL_TTF
01581
01582 }
01583
01584
01585
01586 const string TrueTypeFont::toString( Ceylan::VerbosityLevels level ) const
01587 {
01588
01589 #if OSDL_USES_SDL_TTF
01590
01591 string res = "Truetype font, whose point size is "
01592 + Ceylan::toString( _pointSize ) + " pixel height" ;
01593
01594 if ( ! hasContent() )
01595 return res + ", and which is not loaded" ;
01596
01597 if ( level == Ceylan::low )
01598 return res ;
01599
01600 Ceylan::Uint16 faceCount = getFacesCount() ;
01601
01602 res += ". This font has " ;
01603
01604 switch( faceCount )
01605 {
01606
01607 case 0:
01608 res += "no available face (abnormal)" ;
01609 break ;
01610
01611 case 1:
01612 res += "exactly one face" ;
01613 break ;
01614
01615 default:
01616 res += Ceylan::toString( faceCount ) + " faces" ;
01617 break ;
01618
01619 }
01620
01621 if ( isFixedWidth() )
01622 res +=", and is fixed width" ;
01623 else
01624 res +=", and is not fixed width" ;
01625
01626 res +=". The family name of the current face is '" + getFaceFamilyName()
01627 + "', and its style name is '" + getFaceStyleName() + "'" ;
01628
01629 if ( level == Ceylan::medium )
01630 return res ;
01631
01632 SDL_version compileVersion ;
01633
01634 TTF_VERSION( & compileVersion ) ;
01635
01636 const SDL_version * linkedVersion = ::TTF_Linked_Version() ;
01637
01638 res += ". The OSDL font module is compiled with SDL_ttf version "
01639 + Ceylan::toNumericalString( compileVersion.major ) + "."
01640 + Ceylan::toNumericalString( compileVersion.minor ) + "."
01641 + Ceylan::toNumericalString( compileVersion.patch )
01642 + ", linked with version "
01643 + Ceylan::toNumericalString( linkedVersion->major ) + "."
01644 + Ceylan::toNumericalString( linkedVersion->minor ) + "."
01645 + Ceylan::toNumericalString( linkedVersion->patch ) ;
01646 + ". Rendering style is "
01647 + InterpretRenderingStyle( ::TTF_GetFontStyle( _content ) ) ;
01648
01649
01650 return res ;
01651
01652 #else // OSDL_USES_SDL_TTF
01653
01654 return "" ;
01655
01656 #endif // OSDL_USES_SDL_TTF
01657
01658 }
01659
01660
01661
01662
01663
01664
01665
01666
01667 Font::RenderQuality TrueTypeFont::GetObtainedQualityFor(
01668 Font::RenderQuality targetedQuality )
01669 {
01670
01671 return targetedQuality ;
01672
01673 }
01674
01675
01676
01677 void TrueTypeFont::SetUnicodeSwapStatus( bool newStatus )
01678 {
01679
01680 #if OSDL_USES_SDL_TTF
01681
01682 if ( newStatus )
01683 ::TTF_ByteSwappedUNICODE( 1 ) ;
01684 else
01685 ::TTF_ByteSwappedUNICODE( 0 ) ;
01686
01687 #endif // OSDL_USES_SDL_TTF
01688
01689 }
01690
01691
01692
01693 std::string TrueTypeFont::FindPathFor( const std::string & fontFilename )
01694 {
01695
01696
01697 if ( System::File::ExistsAsFileOrSymbolicLink( fontFilename ) )
01698 {
01699
01700 return fontFilename ;
01701
01702 }
01703 else
01704 {
01705
01706
01707 try
01708 {
01709
01710 return TrueTypeFont::TrueTypeFontFileLocator.find( fontFilename ) ;
01711
01712 }
01713 catch( const System::FileLocatorException & e )
01714 {
01715
01716
01717 try
01718 {
01719
01720 return Font::FontFileLocator.find( fontFilename ) ;
01721
01722 }
01723 catch( const System::FileLocatorException & ex )
01724 {
01725
01726
01727
01728 string currentDir ;
01729
01730 try
01731 {
01732 currentDir = Directory::GetCurrentWorkingDirectoryPath() ;
01733 }
01734 catch( const DirectoryException & exc )
01735 {
01736 throw FontException(
01737 "TrueTypeFont constructor: unable to load '"
01738 + fontFilename
01739 + "', exception generation triggered another failure: "
01740 + exc.toString() + "." ) ;
01741 }
01742
01743 throw FontException( "TrueTypeFont constructor: '"
01744 + fontFilename
01745 + "' is not a regular file or a symbolic link "
01746 "relative to the current directory (" + currentDir
01747 + ") and cannot be found through TrueType font locator ("
01748 + TrueTypeFont::TrueTypeFontFileLocator.toString()
01749 + ") nor through general font locator based on "
01750 "font path environment variable ("
01751 + Font::FontPathEnvironmentVariable + "): "
01752 + Font::FontFileLocator.toString() + "." ) ;
01753
01754 }
01755 }
01756 }
01757
01758 }
01759
01760
01761
01762 string TrueTypeFont::DescribeLastError()
01763 {
01764
01765 #if OSDL_USES_SDL_TTF
01766
01767 string error = string( ::TTF_GetError() ) ;
01768
01769 if ( error.empty() )
01770 return "(no SDL_ttf error detected)" ;
01771 else
01772 return ::TTF_GetError() ;
01773
01774 #else // OSDL_USES_SDL_TTF
01775
01776 return "(no SDL_ttf support available)" ;
01777
01778 #endif // OSDL_USES_SDL_TTF
01779
01780 }
01781
01782
01783
01784 OSDL::Video::Surface & TrueTypeFont::basicRenderUnicodeGlyph(
01785 Ceylan::Unicode character, RenderQuality quality,
01786 Pixels::ColorDefinition glyphColor )
01787 {
01788
01789 #if OSDL_USES_SDL_TTF
01790
01791 if ( ! hasContent() )
01792 throw FontException( "TrueTypeFont::basicRenderUnicodeGlyph failed: "
01793 "font not loaded" ) ;
01794
01795
01796
01797 SDL_Surface * textSurface ;
01798 Surface * res ;
01799
01800 switch( quality )
01801 {
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830 case Solid:
01831 case Shaded:
01832 textSurface = ::TTF_RenderGlyph_Shaded( _content, character,
01833 glyphColor, _backgroundColor ) ;
01834
01835 if ( textSurface == 0 )
01836 throw FontException(
01837 "TrueTypeFont::basicRenderUnicodeGlyph (shaded): "
01838 "unable to render character '"
01839 + Ceylan::toString( character )
01840 + "': " + DescribeLastError() ) ;
01841
01842
01843
01844
01845
01846
01847
01848
01849 ColorMask redMask, greenMask, blueMask ;
01850 Pixels::getRecommendedColorMasks( redMask, greenMask, blueMask ) ;
01851
01852 res = new Surface( Surface::Hardware | Surface::ColorkeyBlit,
01853 textSurface->w, textSurface->h, 32,
01854 redMask, greenMask, blueMask, 0 ) ;
01855
01856
01857 Pixels::ColorDefinition colorKey ;
01858
01859 if ( Pixels::areEqual( glyphColor, Pixels::Black,
01860 false ) )
01861 {
01862
01863 colorKey = Pixels::White ;
01864 res->fill( colorKey ) ;
01865
01866 }
01867 else
01868 {
01869
01870 colorKey = Pixels::Black ;
01871
01872
01873
01874
01875
01876
01877
01878 }
01879
01880 try
01881 {
01882 res->setColorKey(
01883 Surface::ColorkeyBlit | Surface::RLEColorkeyBlit,
01884 Pixels::convertColorDefinitionToPixelColor(
01885 res->getPixelFormat(), colorKey ) ) ;
01886 }
01887 catch( const Video::VideoException & e )
01888 {
01889
01890 throw FontException(
01891 "TrueTypeFont::basicRenderUnicodeGlyph (shaded): "
01892 "color keying failed: " + e.toString() ) ;
01893
01894 }
01895 SDL_BlitSurface( textSurface, 0, & res->getSDLSurface(), 0 ) ;
01896 break ;
01897
01898
01899 case Blended:
01900 textSurface = ::TTF_RenderGlyph_Blended( _content, character,
01901 glyphColor ) ;
01902
01903 if ( textSurface == 0 )
01904 throw FontException(
01905 "TrueTypeFont::basicRenderUnicodeGlyph (blended): "
01906 "unable to render character '"
01907 + Ceylan::toString( character )
01908 + "': " + DescribeLastError() ) ;
01909
01910 res = new Surface( * textSurface,
01911 Surface::BackBuffer ) ;
01912
01913
01914
01915 break ;
01916
01917
01918 default:
01919 throw FontException( "TrueTypeFont::basicRenderUnicodeGlyph: "
01920 "unknown quality requested: "
01921 + Ceylan::toString( quality ) + "." ) ;
01922 break ;
01923
01924 }
01925
01926
01927 if ( _convertToDisplay )
01928 {
01929
01930
01931
01932
01933
01934
01935
01936
01937 if ( quality == Blended )
01938 res->convertToDisplay( true ) ;
01939 else
01940 res->convertToDisplay( false ) ;
01941
01942 }
01943
01944
01945
01946
01947 return * res ;
01948
01949 #else // OSDL_USES_SDL_TTF
01950
01951 throw FontException( "TrueTypeFont::basicRenderUnicodeGlyph failed: "
01952 "no SDL_ttf support available" ) ;
01953
01954 #endif // OSDL_USES_SDL_TTF
01955
01956 }