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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043
00044 #include <OSGConfig.h>
00045
00046 #include <OSGNodePtr.h>
00047 #include <OSGImage.h>
00048
00049 #include <OSGTextTXFFace.h>
00050 #include <OSGTextTXFGlyph.h>
00051 #include <OSGTextLayoutParam.h>
00052 #include <OSGTextLayoutResult.h>
00053
00054 #include <OSGViewport.h>
00055
00056 #include "OSGSimpleStatisticsForeground.h"
00057
00058 #include "OSGStatisticsDefaultFont.h"
00059
00060 OSG_USING_NAMESPACE
00061
00072
00073 SimpleStatisticsForeground::SimpleStatisticsForeground(void) :
00074 Inherited(), _face(0), _texchunk()
00075 {
00076 }
00077
00078 SimpleStatisticsForeground::SimpleStatisticsForeground(const SimpleStatisticsForeground &source) :
00079 Inherited(), _face(source._face), _texchunk(source._texchunk)
00080 {
00081 if (_face != 0)
00082 addRefP(_face);
00083 if (_texchunk != NullFC)
00084 addRefCP(_texchunk);
00085 }
00086
00087
00088 SimpleStatisticsForeground::~SimpleStatisticsForeground(void)
00089 {
00090 if (_face != 0)
00091 subRefP(_face);
00092 if (_texchunk != NullFC)
00093 subRefCP(_texchunk);
00094 }
00095
00096
00097 void SimpleStatisticsForeground::initMethod(void)
00098 {
00099 }
00100
00101
00102 void SimpleStatisticsForeground::changed(BitVector whichField, UInt32 origin)
00103 {
00104 Inherited::changed(whichField, origin);
00105 }
00106
00107
00108 void SimpleStatisticsForeground::dump(UInt32, const BitVector) const
00109 {
00110 SLOG << "Dump SimpleStatisticsForeground NI" << std::endl;
00111 }
00112
00115 void SimpleStatisticsForeground::addElement(StatElemDescBase &desc,
00116 const char *format)
00117 {
00118 getElementIDs().push_back(desc.getID());
00119 getFormats().push_back(format ? format : "");
00120 }
00121
00124 void SimpleStatisticsForeground::addElement(Int32 id, const char *format)
00125 {
00126 getElementIDs().push_back(id);
00127 getFormats().push_back(format ? format : "");
00128 }
00129
00132 void SimpleStatisticsForeground::addText( const char *text )
00133 {
00134 addElement( -1, text );
00135 }
00136
00139 void SimpleStatisticsForeground::clearElems( void )
00140 {
00141 getElementIDs().clear();
00142 getFormats().clear();
00143 getCollector().clearElems();
00144 }
00145
00149 void SimpleStatisticsForeground::initText(const std::string &family, Real32 size)
00150 {
00151
00152 if (_face != 0)
00153 subRefP(_face);
00154 if (_texchunk != NullFC)
00155 subRefCP(_texchunk);
00156
00157
00158 if (family.empty() == false)
00159 {
00160 TextTXFParam param;
00161 param.size = static_cast<UInt32>(size);
00162 _face = TextTXFFace::create(family, TextFace::STYLE_PLAIN, param);
00163 if (_face != 0)
00164 {
00165 _texchunk = TextureChunk::create();
00166 beginEditCP(_texchunk);
00167 {
00168 ImagePtr texture = _face->getTexture();
00169 _texchunk->setImage(texture);
00170 _texchunk->setWrapS(GL_CLAMP);
00171 _texchunk->setWrapT(GL_CLAMP);
00172 _texchunk->setMinFilter(GL_NEAREST);
00173 _texchunk->setMagFilter(GL_NEAREST);
00174 _texchunk->setEnvMode(GL_MODULATE);
00175 }
00176 endEditCP(_texchunk);
00177 }
00178 }
00179
00180
00181 if (_face == 0)
00182 {
00183 _face = getStatisticsDefaultFont();
00184 _texchunk = getStatisticsDefaultFontTexture();
00185 }
00186
00187
00188 addRefP(_face);
00189 addRefCP(_texchunk);
00190 }
00191
00194 void SimpleStatisticsForeground::draw(DrawActionBase *action, Viewport *port)
00195 {
00196 if (getActive() == false)
00197 return;
00198
00199 if (_face == 0)
00200 initText(getFamily(), getSize());
00201
00202 if (!getCollector().getNumOfElems() && !getElementIDs().size())
00203 return;
00204
00205 Real32 pw = Real32(port->getPixelWidth ());
00206 Real32 ph = Real32(port->getPixelHeight());
00207
00208 if (pw < 1 || ph < 1)
00209 return;
00210
00211 glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00212
00213 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00214 glDisable(GL_DEPTH_TEST);
00215 glDisable(GL_COLOR_MATERIAL);
00216 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00217 glEnable(GL_BLEND);
00218
00219 glMatrixMode(GL_MODELVIEW);
00220 glPushMatrix();
00221 glLoadIdentity();
00222
00223 glMatrixMode(GL_PROJECTION);
00224 glPushMatrix();
00225 glLoadIdentity();
00226
00227
00228
00229
00230
00231 glOrtho(0 - 0.375, pw - 0.375, 0 - 0.375, ph - 0.375, 0, 1);
00232
00233
00234 std::vector < std::string > stat;
00235
00236 StatCollector *col = &getCollector();
00237 StatElem *el;
00238
00239 if(getElementIDs().size() != 0)
00240 {
00241 for(UInt32 i = 0; i < getElementIDs().size(); ++i)
00242 {
00243 Int32 id(getElementIDs()[i]);
00244 el = ((id >= 0) ? col->getElem(id) : 0);
00245
00246 stat.resize(stat.size() + 1);
00247 std::vector < std::string >::iterator str = stat.end() - 1;
00248
00249 const char *format = NULL;
00250 if(i < getFormats().size() && getFormats()[i].length())
00251 {
00252 format = getFormats()[i].c_str();
00253 }
00254
00255 if (el)
00256 el->putToString(*str, format);
00257 else
00258 *str = format;
00259 }
00260 }
00261 else
00262 {
00263 for(UInt32 i = 0; i < col->getNumOfElems(); ++i)
00264 {
00265 el = col->getElem(i, false);
00266 if(el)
00267 {
00268 std::string desc(el->getDesc()->getName().str()), eltext;
00269
00270 el->putToString(eltext);
00271 desc = desc + " : " + eltext;
00272
00273 stat.resize(stat.size() + 1);
00274 std::vector < std::string >::iterator str = stat.end() - 1;
00275 *str = desc;
00276 }
00277 }
00278 }
00279
00280 TextLayoutParam layoutParam;
00281 layoutParam.spacing = 1.1;
00282 layoutParam.majorAlignment = TextLayoutParam::ALIGN_BEGIN;
00283 layoutParam.minorAlignment = TextLayoutParam::ALIGN_BEGIN;
00284
00285 TextLayoutResult layoutResult;
00286 _face->layout(stat, layoutParam, layoutResult);
00287
00288 Real32 scale = 1 / _face->getScale();
00289 Real32 size = _face->getParam().size;
00290 Real32 textWidth = layoutResult.textBounds.x() * scale + size + getTextMargin().x() * 2.0f;
00291 Real32 textHeight = layoutResult.textBounds.y() * scale + size + getTextMargin().y() * 2.0f;
00292
00293
00294 Real32 orthoX = 0, orthoY = ph;
00295
00296 switch ( getHorizontalAlign() )
00297 {
00298 case Right:
00299 orthoX = pw - textWidth;
00300 break;
00301 case Middle:
00302 orthoX = (pw - textWidth) * 0.5;
00303 break;
00304 case Left:
00305 default:
00306 break;
00307 }
00308
00309 switch ( getVerticalAlign() )
00310 {
00311 case Bottom:
00312 orthoY = textHeight;
00313 break;
00314 case Center:
00315 orthoY = (ph - textHeight) * 0.5 + textHeight;
00316 break;
00317 case Top:
00318 default:
00319 break;
00320 }
00321
00322 glTranslatef(orthoX, orthoY, 0.0);
00323
00324
00325 glColor4fv((GLfloat*)getBgColor().getValuesRGBA());
00326 glBegin(GL_QUADS);
00327 glVertex2f(0, -textHeight);
00328 glVertex2f(textWidth, -textHeight);
00329 glVertex2f(textWidth, 0);
00330 glVertex2f(0, 0);
00331 glEnd();
00332
00333
00334 if(getBorderColor().red() >= 0.0f)
00335 {
00336 glColor4fv((GLfloat*)getBorderColor().getValuesRGBA());
00337 glBegin(GL_LINE_LOOP);
00338 glVertex2f(getBorderOffset().x(), -textHeight + 1 + getBorderOffset().y());
00339 glVertex2f(textWidth - 1 - getBorderOffset().x(), -textHeight + 1 + getBorderOffset().y());
00340 glVertex2f(textWidth - 1 - getBorderOffset().x(), -1 - getBorderOffset().y());
00341 glVertex2f(getBorderOffset().x(), -1 - getBorderOffset().y());
00342 glEnd();
00343 }
00344
00345
00346 glTranslatef(0.5 * size + getTextMargin().x(), -0.5 * size - getTextMargin().y(), 0.0);
00347
00348 _texchunk->activate(action);
00349
00350 glColor4fv((GLfloat*)getShadowColor().getValuesRGBA());
00351 glPushMatrix();
00352 glTranslatef(getShadowOffset().x(), getShadowOffset().y(), 0);
00353 glScalef(scale, scale, 1);
00354 drawCharacters(layoutResult);
00355
00356 glColor4fv((GLfloat*)getColor().getValuesRGBA());
00357 glPopMatrix();
00358 glScalef(scale, scale, 1);
00359 drawCharacters(layoutResult);
00360
00361 _texchunk->deactivate(action);
00362
00363 glMatrixMode(GL_PROJECTION);
00364 glPopMatrix();
00365
00366 glMatrixMode(GL_MODELVIEW);
00367 glPopMatrix();
00368
00369 glPopAttrib();
00370 }
00371
00372 void SimpleStatisticsForeground::drawCharacters(const TextLayoutResult &layoutResult) const
00373 {
00374 glBegin(GL_QUADS);
00375
00376 UInt32 i, numGlyphs = layoutResult.getNumGlyphs();
00377 Real32 width, height;
00378 for(i = 0; i < numGlyphs; ++i)
00379 {
00380 const TextTXFGlyph &glyph = _face->getTXFGlyph(layoutResult.indices[i]);
00381 width = glyph.getWidth();
00382 height = glyph.getHeight();
00383
00384 if ((width <= 0.f) || (height <= 0.f))
00385 continue;
00386
00387
00388 const Vec2f &pos = layoutResult.positions[i];
00389 Real32 posLeft = pos.x();
00390 Real32 posTop = pos.y();
00391 Real32 posRight = pos.x() + width;
00392 Real32 posBottom = pos.y() - height;
00393 Real32 texCoordLeft = glyph.getTexCoord(TextTXFGlyph::COORD_LEFT);
00394 Real32 texCoordTop = glyph.getTexCoord(TextTXFGlyph::COORD_TOP);
00395 Real32 texCoordRight = glyph.getTexCoord(TextTXFGlyph::COORD_RIGHT);
00396 Real32 texCoordBottom = glyph.getTexCoord(TextTXFGlyph::COORD_BOTTOM);
00397
00398
00399 glTexCoord2f(texCoordLeft, texCoordBottom);
00400 glVertex2f(posLeft, posBottom);
00401
00402
00403 glTexCoord2f(texCoordRight, texCoordBottom);
00404 glVertex2f(posRight, posBottom);
00405
00406
00407 glTexCoord2f(texCoordRight, texCoordTop);
00408 glVertex2f(posRight, posTop);
00409
00410
00411 glTexCoord2f(texCoordLeft, texCoordTop);
00412 glVertex2f(posLeft, posTop);
00413 }
00414
00415 glEnd();
00416 }
00417
00418
00419
00420 #ifdef __sgi
00421 #pragma set woff 1174
00422 #endif
00423 #ifdef OSG_LINUX_ICC
00424 #pragma warning(disable : 177)
00425 #endif
00426 namespace
00427 {
00428 static char cvsid_cpp[] = "@(#)$Id: OSGSimpleStatisticsForeground.cpp,v 1.11 2002/08/07 04:04:13 vossg Exp $";
00429 static char cvsid_hpp[] = OSGSIMPLESTATISTICSFOREGROUND_HEADER_CVSID;
00430 static char cvsid_inl[] = OSGSIMPLESTATISTICSFOREGROUND_INLINE_CVSID;
00431 }