diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2014-10-26 12:33:50 +0400 |
commit | 47e6e7c84f008a53061e661f31ae96629bc694ef (patch) | |
tree | 648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/pmview/text.cpp | |
download | pcp-debian/3.9.10.tar.gz |
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/pmview/text.cpp')
-rw-r--r-- | src/pmview/text.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/src/pmview/text.cpp b/src/pmview/text.cpp new file mode 100644 index 0000000..f4547b4 --- /dev/null +++ b/src/pmview/text.cpp @@ -0,0 +1,334 @@ +/* + * Copyright (c) 1995 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2009 Aconex. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <Inventor/Qt/viewers/SoQtExaminerViewer.h> +#include <Inventor/actions/SoGetBoundingBoxAction.h> +#include <Inventor/nodes/SoPickStyle.h> +#include <Inventor/nodes/SoTranslation.h> +#include <Inventor/nodes/SoRotation.h> +#include <Inventor/nodes/SoCube.h> +#include "main.h" +#include "text.h" + +#include <iostream> +using namespace std; + +const char *Text::theHeightStr = "gjpqy|_"; + +SoFont *Text::theSmallFont = (SoFont *)0; +SoFont *Text::theMediumFont = (SoFont *)0; +SoFont *Text::theLargeFont = (SoFont *)0; + +SbVec3f Text::theColor(1.0, 1.0, 1.0); +SoGetBoundingBoxAction *Text::theBoxAction = (SoGetBoundingBoxAction *)0; + +Text::~Text() +{ +} + +Text::Text(const QString &theString, + Direction theDir, + FontSize theFontSize, + bool rightJust) +: _width(0), + _depth(0), + _dir(theDir), + _fontSize(theFontSize), + _rightJustFlag(rightJust), + _root(0), + _translation(0) +{ + float x = 0.0; + float y = 0.0; + float z = 0.0; + int width = 0; + int height = 0; + SoRotation *rot1; + SoRotation *rot2; + SoText3 *theText; + + _root = new SoSeparator; + _translation = new SoTranslation; + theText = new SoText3; + + SoPickStyle *style = new SoPickStyle; + style->style = SoPickStyle::UNPICKABLE; + _root->addChild(style); + + if (theSmallFont == (SoFont *)0) { + char * font = getenv ("PMVIEW_FONT"); + + theSmallFont = new SoFont; + theMediumFont = new SoFont; + theLargeFont = new SoFont; + + if ( font != NULL ) { + theSmallFont->name.setValue(font); + theMediumFont->name.setValue(font); + theLargeFont->name.setValue(font); +#ifdef __sgi + } else { + // On Irix we know that Helvetica-Narrow is shipped as part + // of x_eoe.sw.Xfonts, so we're going to use it since it's + // an easier font to render compared to Times. + theSmallFont->name.setValue("Helvetica-Narrow"); + theMediumFont->name.setValue("Helvetica-Narrow"); + theLargeFont->name.setValue("Helvetica-Narrow"); +#endif + } + + theSmallFont->size.setValue(14); + theMediumFont->size.setValue(24); + theLargeFont->size.setValue(32); + theSmallFont->ref(); + theMediumFont->ref(); + theLargeFont->ref(); + theBoxAction = new SoGetBoundingBoxAction(pmview->viewer()->getViewportRegion()); + } + + switch(_fontSize) { + case small: + _root->addChild(theSmallFont->copy()); + break; + case medium: + _root->addChild(theMediumFont->copy()); + break; + case large: + _root->addChild(theLargeFont->copy()); + break; + default: +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL1) + cerr << "Text::Text: Illegal size specified" << endl; +#endif + _fontSize = medium; + _root->addChild(theMediumFont->copy()); + } + + _translation->translation.setValue(0.0, 0.0, 0.0); + _root->addChild(_translation); + +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL1) { + SoSeparator *sep = new SoSeparator; + _root->addChild(sep); + SoBaseColor *col = new SoBaseColor; + col->rgb.setValue(1.0, 0.0, 0.0); + sep->addChild(col); + SoCube *cube = new SoCube; + cube->width.setValue(3); + cube->depth.setValue(3); + cube->height.setValue(20); + sep->addChild(cube); + } +#endif + + if (_dir != vertical) { + + rot1 = new SoRotation; + rot1->rotation.setValue(SbVec3f(1,0,0), -M_PI/2); + _root->addChild(rot1); + + switch(_dir) { + case left: + rot2 = new SoRotation; + rot2->rotation.setValue(SbVec3f(0,0,1), M_PI); + _root->addChild(rot2); + break; + case down: + rot2 = new SoRotation; + rot2->rotation.setValue(SbVec3f(0,0,1), -M_PI/2); + _root->addChild(rot2); + break; + case up: + rot2 = new SoRotation; + rot2->rotation.setValue(SbVec3f(0,0,1), M_PI/2); + _root->addChild(rot2); + break; + default: + break; + } + + if (((_dir == left || _dir == up) && !_rightJustFlag) || + ((_dir == right || _dir == down) && !_rightJustFlag)) { + theText->justification = SoText3::RIGHT; + } + + theText->parts = SoText3::FRONT; + theText->string.setValue((const char *)theString.toAscii()); + _root->addChild(theText); + + _root->ref(); + theBoxAction->apply(_root); + SbXfBox3f box = theBoxAction->getBoundingBox(); + box.getSize(x, y, z); + + if (x < 0.0 || y < 0.0 || z < 0.0) { +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL2) { + cerr << "Text::Text: Bogus bounding box returned for \"" + << theString << "\": x = " << x << ", y = " << y + << ", z = " << z << endl; + } +#endif + x = 0.0; + y = 0.0; + z = 0.0; + } + + _width = (int)ceilf(x); + _depth = (int)ceilf(z); + + const char *hasLow = strpbrk((const char *)theString.toAscii(), theHeightStr); + +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL1) { + cerr << "Text::Text: " << theString << ": width = " + << _width << " height = " << _depth << " low = " + << ((hasLow != (char *)0) ? 1 : 0) << endl; + } +#endif + + switch(_dir) { + case left: + if (hasLow != (char *)0) { + _translation->translation.setValue(1, 1, _depth * 0.3); + _depth = (int)(_depth * 1.2); + } + else + _translation->translation.setValue(1, 1, 0); + _width += 2; + break; + case right: + if (hasLow != (char *)0) { + _translation->translation.setValue(1, 1, _depth * 0.85); + _depth = (int)(_depth * 1.2); + } + else + _translation->translation.setValue(1, 1, _depth); + _width += 2; + break; + case down: + if (hasLow != (char *)0) { + _translation->translation.setValue(_width * 0.3, 1, 1); + _width = (int)(_width * 1.2); + } + else + _translation->translation.setValue(0, 1, 1); + _depth += 2; + break; + case up: + if (hasLow != (char *)0) { + _translation->translation.setValue(_width * 0.85, 1, 1); + _width = (int)(_width * 1.2); + } + else + _translation->translation.setValue(_width, 1, 1); + _depth += 2; + break; + default: +#ifdef PCP_DEBUG + if (pmDebug & DBG_TRACE_APPL1) + cerr << "Text::Text: Illegal direction specified (" + << (int)_dir << ")" << endl; +#endif + break; + } + } + else { + char c[2] = { ' ', '\0' }; + SoSeparator *sep; + SoTranslation *tran; + SoRotation *rot; + width = 0; + height = 0; + + for (int i = 0; i < theString.length(); i++) { + c[0] = ((const char *)theString.toAscii())[i]; + sep = new SoSeparator; + tran = new SoTranslation; + rot = new SoRotation; + rot->rotation.setValue(SbVec3f(1,0,0), -M_PI/2); + theText->string.setValue(c); + theText->parts = SoText3::FRONT; + + _root->addChild(sep); + sep->addChild(rot); + sep->addChild(tran); + sep->addChild(theText); + + theBoxAction->apply(sep); + SbXfBox3f box = theBoxAction->getBoundingBox(); + box.getSize(x, y, z); + + width = (int)ceilf(x); + height = (int)ceilf(z); + +// TODO: This bounding box is wrong. + + if (width*2 > _width) + _width = width*2; + + _depth += (height + 2) * 2; + + tran->translation.setValue(0, -_depth, 1); + + if (i < theString.length() - 1) { + theText = new SoText3; + } + } + } +} + + +QTextStream& +operator<<(QTextStream& os, Text const& rhs) +{ + rhs.display(os); + return os; +} + +void +Text::display(QTextStream& os) const +{ + os << "Text: dir = "; + switch(_dir) { + case left: + os << "left"; + break; + case right: + os << "right"; + break; + case up: + os << "up"; + break; + case down: + os << "down"; + break; + default: + break; + } + os << ", font size = "; + switch(_fontSize) { + case small: + os << "small"; + break; + case medium: + os << "medium"; + break; + case large: + os << "large"; + break; + } +} |