![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cGuiTextStyle.cppGo to the documentation of this file.00001 /************************************************************************ 00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library 00003 Copyright (C) 2002 Aaron Cameron 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 A copy of the GNU Lesser General Public License has been provided with 00020 this library in the file 'COPYING'. 00021 00022 Contact information for the author of this library has been provided 00023 with this library in the file 'AUTHOR'. 00024 ************************************************************************/ 00025 #include "gui/cGuiTextStyle.h" 00026 00027 #include "n2l/dynVars.h" 00028 #include "n2l/resourceManagement.h" 00029 00030 #include "gui/cGuiElement.h" 00031 00032 /******************************************************************************/ 00033 namespace n2l 00034 { 00035 00036 /**************************************************************************/ 00037 cGuiTextStyle::cGuiTextStyle() : 00038 mColourInherit(true), 00039 mColour(1.0f,1.0f,1.0f,1.0f), 00040 mFontHeight(0.0f), 00041 mFont(0), 00042 mAlign( Align_Left ), 00043 mVAlign( VAlign_Top ), 00044 mClipping( Clipping_Letter ) 00045 { 00046 } 00047 00048 /**************************************************************************/ 00049 cGuiTextStyle::cGuiTextStyle( const cVfsNodeInterface & iNode ) : 00050 mColourInherit(true), 00051 mColour(1.0f,1.0f,1.0f,1.0f), 00052 mFontHeight(0.0f), 00053 mFont(0), 00054 mAlign( Align_Left ), 00055 mVAlign( VAlign_Top ), 00056 mClipping( Clipping_Letter ) 00057 { 00058 load( iNode ); 00059 } 00060 00061 /**************************************************************************/ 00062 cGuiTextStyle::cGuiTextStyle( const cDynVar &iDef ) : 00063 mColourInherit(true), 00064 mColour(1.0f,1.0f,1.0f,1.0f), 00065 mFontHeight(0.0f), 00066 mFont(0), 00067 mAlign( Align_Left ), 00068 mVAlign( VAlign_Top ), 00069 mClipping( Clipping_Letter ) 00070 { 00071 load( iDef ); 00072 } 00073 00074 /**************************************************************************/ 00075 cGuiTextStyle::~cGuiTextStyle() 00076 { 00077 } 00078 00079 /**************************************************************************/ 00080 void cGuiTextStyle::load( const cVfsNodeInterface & iNode ) 00081 { 00082 cDynVar def; 00083 cGuiElement::validateAndDecode( def, iNode, "n2l::cGuiTextStyle" ); 00084 load( def ); 00085 } 00086 00087 00088 /**************************************************************************/ 00089 void cGuiTextStyle::load( const cDynVar &iDef ) 00090 { 00091 if (iDef.keyExists("font")) 00092 font( cResourceManager::get<cTextureFont>(iDef["font"]) ); 00093 00094 if (iDef.keyExists("fontHeight")) 00095 fontHeight( iDef["fontHeight"] ); 00096 00097 if (iDef.keyExists("colour")) 00098 colour( iDef["colour"] ); 00099 00100 if (iDef.keyExists("colourInherit")) 00101 colourInherit( iDef["colourInherit"] ); 00102 00103 if (iDef.keyExists("align")) 00104 align( tAlign(tSint(iDef["align"])) ); 00105 00106 if (iDef.keyExists("vAlign")) 00107 vAlign( tVAlign(tSint(iDef["vAlign"])) ); 00108 00109 if (iDef.keyExists("clipping")) 00110 clipping( tClipping(tSint(iDef["clipping"])) ); 00111 00112 } 00113 00114 /**************************************************************************/ 00115 void cGuiTextStyle::font( const cAutoPtr<const cFontInterface> & i_iFont ) 00116 { 00117 mFont = i_iFont; 00118 } 00119 00120 /**************************************************************************/ 00121 const cAutoPtr<const cFontInterface> & cGuiTextStyle::font() const 00122 { 00123 return mFont; 00124 } 00125 00126 /**************************************************************************/ 00127 void cGuiTextStyle::fontHeight( const tFloat & iFontHeight ) 00128 { 00129 mFontHeight = iFontHeight; 00130 } 00131 00132 /**************************************************************************/ 00133 const tFloat & cGuiTextStyle::fontHeight() const 00134 { 00135 return mFontHeight; 00136 } 00137 00138 /**************************************************************************/ 00139 void cGuiTextStyle::colour( const tGuiColour & iColour ) 00140 { 00141 mColourInherit = false; 00142 mColour = iColour; 00143 } 00144 00145 00146 /**************************************************************************/ 00147 void cGuiTextStyle::colourInherit( const tBool iValue ) 00148 { 00149 mColourInherit = iValue; 00150 } 00151 00152 /**************************************************************************/ 00153 void cGuiTextStyle::align( const tAlign iAlign ) 00154 { 00155 alignInBounds( iAlign ); 00156 mAlign = iAlign; 00157 } 00158 00159 /**************************************************************************/ 00160 void cGuiTextStyle::vAlign( const tVAlign iVAlign ) 00161 { 00162 vAlignInBounds( iVAlign ); 00163 mVAlign = iVAlign; 00164 } 00165 00166 /**************************************************************************/ 00167 void cGuiTextStyle::clipping( const tClipping iClipping ) 00168 { 00169 clippingInBounds( iClipping ); 00170 mClipping = iClipping; 00171 } 00172 00173 00174 /**************************************************************************/ 00175 const tString::size_type cGuiTextStyle::draw( const tGuiPos &iPos, 00176 const tGuiPos &iSize, const tString &iText, 00177 const tString::size_type iSPos, 00178 const tString::size_type iMaxSize ) const 00179 { 00180 if (!mFont.isSet()) return 0; 00181 if (iText.empty()) return 0; 00182 00183 tGuiPos finalPos; 00184 tFloat glyphHeight; 00185 tString::size_type sPos,ePos, charactersDrawn; 00186 00187 commonDraw( iPos, iSize, iText, iSPos, iMaxSize, 00188 charactersDrawn, finalPos, glyphHeight, sPos,ePos ); 00189 00190 if (!mColourInherit) mColour.glColour4(); 00191 00192 glPushAttrib( GL_ALL_ATTRIB_BITS ); 00193 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); 00194 glEnable( GL_BLEND ); 00195 // glDisable( GL_DEPTH_TEST ); 00196 00197 glEnable( GL_TEXTURE_2D ); 00198 00199 glCullFace( GL_BACK ); 00200 glEnable( GL_CULL_FACE ); 00201 00202 mFont->draw( finalPos, iText, glyphHeight, iSPos, ePos-sPos ); 00203 glPopAttrib(); 00204 00205 return ePos-sPos; 00206 } 00207 00208 /**************************************************************************/ 00209 const tString::size_type cGuiTextStyle::wouldDraw( 00210 const tGuiPos & iSize, const tString & iText, 00211 const tString::size_type iSPos, 00212 const tString::size_type iMaxSize ) const 00213 { 00214 if (!mFont.isSet()) return 0; 00215 00216 tGuiPos finalPos; 00217 tFloat glyphHeight; 00218 tString::size_type sPos,ePos, charactersDrawn; 00219 00220 const tGuiPos AnyPos(0,0); 00221 commonDraw( AnyPos, iSize, iText, iSPos, iMaxSize, 00222 charactersDrawn, finalPos, glyphHeight, sPos,ePos ); 00223 00224 return ePos-sPos; 00225 } 00226 00227 /**************************************************************************/ 00228 const tFloat cGuiTextStyle::calcGlyphHeight( const tGuiPos &iSize ) const 00229 { 00230 return (mFontHeight>0?mFontHeight:iSize.y()); 00231 } 00232 00233 /**************************************************************************/ 00234 void cGuiTextStyle::prop( const tString &iName, const cDynVar &iVal ) 00235 { 00236 if (iName == "colour") 00237 colour( iVal ); 00238 00239 else if (iName == "colourInherit") 00240 colourInherit( iVal ); 00241 00242 else if (iName == "fontHeight") 00243 fontHeight( iVal ); 00244 } 00245 00246 /**************************************************************************/ 00247 const cDynVar cGuiTextStyle::prop( const tString &iName ) const 00248 { 00249 cDynVar oVal = cDynVar::Null; 00250 00251 if (iName == "colour") { 00252 oVal = cDynVar::Array; 00253 oVal.insert(mColour.r()); 00254 oVal.insert(mColour.g()); 00255 oVal.insert(mColour.b()); 00256 oVal.insert(mColour.a()); 00257 00258 } 00259 00260 return oVal; 00261 } 00262 00263 00264 /**************************************************************************/ 00265 void cGuiTextStyle::commonDraw( const tGuiPos &iPos, const tGuiPos &iSize, 00266 const tString &iText, const tString::size_type iSPos, 00267 const tString::size_type iMaxSize, 00268 tString::size_type &oCharactersDrawn, tGuiPos &oFinalPos, 00269 tFloat &oGlyphHeight, tString::size_type &oSPos, 00270 tString::size_type &oCEndPos ) const 00271 { 00272 tString::size_type strLength( iText.size() ); 00273 if (iMaxSize>0) 00274 strLength = n2l_min( strLength, iSPos+iMaxSize ); 00275 00276 const tFloat GlyphHeight = (mFontHeight>0?mFontHeight:iSize.y()); 00277 const tFloat GlyphSeperation = mFont->glyphSeperation(GlyphHeight); 00278 00279 if (!mFont || !strLength || iSPos>=strLength) { 00280 oSPos = iSPos; 00281 oGlyphHeight = GlyphHeight; 00282 oCEndPos = iSPos; 00283 return; 00284 } 00285 00286 // Calculate how many characters we're going to draw. 00287 tString::size_type cEndPos(iSPos); 00288 00289 tFloat strWidth( 0.0f ); 00290 tFloat whiteSpaceStrWidth( 0.0f ); 00291 00292 if (mClipping != Clipping_NoClip) { 00293 tString::size_type cLastWhitespace(iSPos); 00294 tBool clip = false; 00295 while (!clip && cEndPos<strLength) { 00296 const tFloat ExtraSpace(cEndPos==iSPos?0:GlyphSeperation); 00297 const tFloat GlyphWidth( ExtraSpace + 00298 mFont->glyphWidth(iText[cEndPos],GlyphHeight) ); 00299 00300 if (strWidth+GlyphWidth>iSize.x()) { 00301 clip = true; 00302 continue; 00303 } 00304 strWidth += GlyphWidth; 00305 if (iText[cEndPos]==' ' || iText[cEndPos]=='\t' || 00306 iText[cEndPos]=='\n') 00307 { 00308 cLastWhitespace = cEndPos; 00309 whiteSpaceStrWidth = strWidth; 00310 } 00311 // Up the position. 00312 00313 ++cEndPos; 00314 } 00315 if (cEndPos!=strLength) { 00316 // What to do with the values we have here. 00317 switch (mClipping) { 00318 case Clipping_Letter: 00319 // We'll use the last character to fit as a clip point 00320 // so we have nothing more to do 00321 break; 00322 00323 case Clipping_Word: 00324 if (cLastWhitespace==iSPos) { 00325 oSPos = iSPos; 00326 oCEndPos = iSPos; 00327 oGlyphHeight = GlyphHeight; 00328 return; 00329 } 00330 else { 00331 cEndPos = cLastWhitespace; 00332 strWidth = whiteSpaceStrWidth; 00333 } 00334 break; 00335 00336 case Clipping_HardWord: 00337 if (cLastWhitespace!=iSPos) { 00338 cEndPos = cLastWhitespace; 00339 strWidth = whiteSpaceStrWidth; 00340 } 00341 // Else we leave it at the last character 00342 // splitting pos. 00343 break; 00344 00345 default: 00346 // We shouldn't be able to get here. 00347 //Added for completeness 00348 cEndPos = strLength; 00349 break; 00350 } // switch 00351 } 00352 } else { // if (mClipping != Clipping_NoClip) 00353 cEndPos = strLength; 00354 strWidth = mFont->calcSize( iText, GlyphHeight, iSPos, 00355 cEndPos-iSPos ).x(); 00356 } 00357 00358 // Get the final rendering positions 00359 tGuiPos finalPos(iPos); 00360 switch (mAlign) 00361 { 00362 case Align_Right: 00363 finalPos.x( (iPos.x() + iSize.x()) - strWidth ); 00364 break; 00365 case Align_Center: 00366 finalPos.x( (iPos.x() + iSize.x()/2.0f) - strWidth/2.0f ); 00367 break; 00368 default: 00369 break; 00370 } // switch 00371 00372 switch (mVAlign) 00373 { 00374 case VAlign_Middle: 00375 finalPos.y( (iPos.y() + iSize.y()/2.0f) - GlyphHeight/2.0f ); 00376 break; 00377 case VAlign_Bottom: 00378 finalPos.y( (iPos.y() + iSize.y()) - GlyphHeight ); 00379 break; 00380 default: 00381 break; 00382 } // switch 00383 00384 // Set the outgoing values. 00385 oFinalPos = finalPos; 00386 oGlyphHeight = GlyphHeight; 00387 oSPos = iSPos; 00388 oCEndPos = cEndPos; 00389 } 00390 00391 /**************************************************************************/ 00392 void cGuiTextStyle::alignInBounds( const tAlign iAlign ) const 00393 { 00394 if (iAlign<0 || iAlign>=Align_NumAligns) 00395 throw cOutOfBoundsException( "cGuiTextStyle::alignInBounds", 00396 "Alignment value illegal" ); 00397 } 00398 00399 00400 /**************************************************************************/ 00401 void cGuiTextStyle::vAlignInBounds( const tVAlign iVAlign ) const 00402 { 00403 if (iVAlign<0 || iVAlign>=VAlign_NumVAligns) 00404 throw cOutOfBoundsException( "cGuiTextStyle::vAlignInBounds", 00405 "Vertical Alignment value illegal" ); 00406 } 00407 00408 00409 /**************************************************************************/ 00410 void cGuiTextStyle::clippingInBounds( const tClipping iClipping ) const 00411 { 00412 if (iClipping<0 || iClipping>=Clipping_NumClippings) 00413 throw cOutOfBoundsException( "cGuiTextStyle::clippingInBounds", 00414 "Clipping value illegal" ); 00415 } 00416 00417 00418 } // namespace n2l |