docs: describe the pmdaroot process interfaces
[pcp.git] / src / pmview / text.cpp
blob8fa8259c129cf66465b91f6074e3f9a5ca86c5b8
1 /*
2 * Copyright (c) 1995 Silicon Graphics, Inc. All Rights Reserved.
3 * Copyright (c) 2009 Aconex. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
15 #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
16 #include <Inventor/actions/SoGetBoundingBoxAction.h>
17 #include <Inventor/nodes/SoPickStyle.h>
18 #include <Inventor/nodes/SoTranslation.h>
19 #include <Inventor/nodes/SoRotation.h>
20 #include <Inventor/nodes/SoCube.h>
21 #include "main.h"
22 #include "text.h"
24 #include <iostream>
25 using namespace std;
27 const char *Text::theHeightStr = "gjpqy|_";
29 SoFont *Text::theSmallFont = (SoFont *)0;
30 SoFont *Text::theMediumFont = (SoFont *)0;
31 SoFont *Text::theLargeFont = (SoFont *)0;
33 SbVec3f Text::theColor(1.0, 1.0, 1.0);
34 SoGetBoundingBoxAction *Text::theBoxAction = (SoGetBoundingBoxAction *)0;
36 Text::~Text()
40 Text::Text(const QString &theString,
41 Direction theDir,
42 FontSize theFontSize,
43 bool rightJust)
44 : _width(0),
45 _depth(0),
46 _dir(theDir),
47 _fontSize(theFontSize),
48 _rightJustFlag(rightJust),
49 _root(0),
50 _translation(0)
52 float x = 0.0;
53 float y = 0.0;
54 float z = 0.0;
55 int width = 0;
56 int height = 0;
57 SoRotation *rot1;
58 SoRotation *rot2;
59 SoText3 *theText;
61 _root = new SoSeparator;
62 _translation = new SoTranslation;
63 theText = new SoText3;
65 SoPickStyle *style = new SoPickStyle;
66 style->style = SoPickStyle::UNPICKABLE;
67 _root->addChild(style);
69 if (theSmallFont == (SoFont *)0) {
70 char * font = getenv ("PMVIEW_FONT");
72 theSmallFont = new SoFont;
73 theMediumFont = new SoFont;
74 theLargeFont = new SoFont;
76 if ( font != NULL ) {
77 theSmallFont->name.setValue(font);
78 theMediumFont->name.setValue(font);
79 theLargeFont->name.setValue(font);
80 #ifdef __sgi
81 } else {
82 // On Irix we know that Helvetica-Narrow is shipped as part
83 // of x_eoe.sw.Xfonts, so we're going to use it since it's
84 // an easier font to render compared to Times.
85 theSmallFont->name.setValue("Helvetica-Narrow");
86 theMediumFont->name.setValue("Helvetica-Narrow");
87 theLargeFont->name.setValue("Helvetica-Narrow");
88 #endif
91 theSmallFont->size.setValue(14);
92 theMediumFont->size.setValue(24);
93 theLargeFont->size.setValue(32);
94 theSmallFont->ref();
95 theMediumFont->ref();
96 theLargeFont->ref();
97 theBoxAction = new SoGetBoundingBoxAction(pmview->viewer()->getViewportRegion());
100 switch(_fontSize) {
101 case small:
102 _root->addChild(theSmallFont->copy());
103 break;
104 case medium:
105 _root->addChild(theMediumFont->copy());
106 break;
107 case large:
108 _root->addChild(theLargeFont->copy());
109 break;
110 default:
111 #ifdef PCP_DEBUG
112 if (pmDebug & DBG_TRACE_APPL1)
113 cerr << "Text::Text: Illegal size specified" << endl;
114 #endif
115 _fontSize = medium;
116 _root->addChild(theMediumFont->copy());
119 _translation->translation.setValue(0.0, 0.0, 0.0);
120 _root->addChild(_translation);
122 #ifdef PCP_DEBUG
123 if (pmDebug & DBG_TRACE_APPL1) {
124 SoSeparator *sep = new SoSeparator;
125 _root->addChild(sep);
126 SoBaseColor *col = new SoBaseColor;
127 col->rgb.setValue(1.0, 0.0, 0.0);
128 sep->addChild(col);
129 SoCube *cube = new SoCube;
130 cube->width.setValue(3);
131 cube->depth.setValue(3);
132 cube->height.setValue(20);
133 sep->addChild(cube);
135 #endif
137 if (_dir != vertical) {
139 rot1 = new SoRotation;
140 rot1->rotation.setValue(SbVec3f(1,0,0), -M_PI/2);
141 _root->addChild(rot1);
143 switch(_dir) {
144 case left:
145 rot2 = new SoRotation;
146 rot2->rotation.setValue(SbVec3f(0,0,1), M_PI);
147 _root->addChild(rot2);
148 break;
149 case down:
150 rot2 = new SoRotation;
151 rot2->rotation.setValue(SbVec3f(0,0,1), -M_PI/2);
152 _root->addChild(rot2);
153 break;
154 case up:
155 rot2 = new SoRotation;
156 rot2->rotation.setValue(SbVec3f(0,0,1), M_PI/2);
157 _root->addChild(rot2);
158 break;
159 default:
160 break;
163 if (((_dir == left || _dir == up) && !_rightJustFlag) ||
164 ((_dir == right || _dir == down) && !_rightJustFlag)) {
165 theText->justification = SoText3::RIGHT;
168 theText->parts = SoText3::FRONT;
169 theText->string.setValue((const char *)theString.toLatin1());
170 _root->addChild(theText);
172 _root->ref();
173 theBoxAction->apply(_root);
174 SbXfBox3f box = theBoxAction->getBoundingBox();
175 box.getSize(x, y, z);
177 if (x < 0.0 || y < 0.0 || z < 0.0) {
178 #ifdef PCP_DEBUG
179 if (pmDebug & DBG_TRACE_APPL2) {
180 cerr << "Text::Text: Bogus bounding box returned for \""
181 << theString << "\": x = " << x << ", y = " << y
182 << ", z = " << z << endl;
184 #endif
185 x = 0.0;
186 y = 0.0;
187 z = 0.0;
190 _width = (int)ceilf(x);
191 _depth = (int)ceilf(z);
193 const char *hasLow = strpbrk((const char *)theString.toLatin1(), theHeightStr);
195 #ifdef PCP_DEBUG
196 if (pmDebug & DBG_TRACE_APPL1) {
197 cerr << "Text::Text: " << theString << ": width = "
198 << _width << " height = " << _depth << " low = "
199 << ((hasLow != (char *)0) ? 1 : 0) << endl;
201 #endif
203 switch(_dir) {
204 case left:
205 if (hasLow != (char *)0) {
206 _translation->translation.setValue(1, 1, _depth * 0.3);
207 _depth = (int)(_depth * 1.2);
209 else
210 _translation->translation.setValue(1, 1, 0);
211 _width += 2;
212 break;
213 case right:
214 if (hasLow != (char *)0) {
215 _translation->translation.setValue(1, 1, _depth * 0.85);
216 _depth = (int)(_depth * 1.2);
218 else
219 _translation->translation.setValue(1, 1, _depth);
220 _width += 2;
221 break;
222 case down:
223 if (hasLow != (char *)0) {
224 _translation->translation.setValue(_width * 0.3, 1, 1);
225 _width = (int)(_width * 1.2);
227 else
228 _translation->translation.setValue(0, 1, 1);
229 _depth += 2;
230 break;
231 case up:
232 if (hasLow != (char *)0) {
233 _translation->translation.setValue(_width * 0.85, 1, 1);
234 _width = (int)(_width * 1.2);
236 else
237 _translation->translation.setValue(_width, 1, 1);
238 _depth += 2;
239 break;
240 default:
241 #ifdef PCP_DEBUG
242 if (pmDebug & DBG_TRACE_APPL1)
243 cerr << "Text::Text: Illegal direction specified ("
244 << (int)_dir << ")" << endl;
245 #endif
246 break;
249 else {
250 char c[2] = { ' ', '\0' };
251 SoSeparator *sep;
252 SoTranslation *tran;
253 SoRotation *rot;
254 width = 0;
255 height = 0;
257 for (int i = 0; i < theString.length(); i++) {
258 c[0] = ((const char *)theString.toLatin1())[i];
259 sep = new SoSeparator;
260 tran = new SoTranslation;
261 rot = new SoRotation;
262 rot->rotation.setValue(SbVec3f(1,0,0), -M_PI/2);
263 theText->string.setValue(c);
264 theText->parts = SoText3::FRONT;
266 _root->addChild(sep);
267 sep->addChild(rot);
268 sep->addChild(tran);
269 sep->addChild(theText);
271 theBoxAction->apply(sep);
272 SbXfBox3f box = theBoxAction->getBoundingBox();
273 box.getSize(x, y, z);
275 width = (int)ceilf(x);
276 height = (int)ceilf(z);
278 // TODO: This bounding box is wrong.
280 if (width*2 > _width)
281 _width = width*2;
283 _depth += (height + 2) * 2;
285 tran->translation.setValue(0, -_depth, 1);
287 if (i < theString.length() - 1) {
288 theText = new SoText3;
295 QTextStream&
296 operator<<(QTextStream& os, Text const& rhs)
298 rhs.display(os);
299 return os;
302 void
303 Text::display(QTextStream& os) const
305 os << "Text: dir = ";
306 switch(_dir) {
307 case left:
308 os << "left";
309 break;
310 case right:
311 os << "right";
312 break;
313 case up:
314 os << "up";
315 break;
316 case down:
317 os << "down";
318 break;
319 default:
320 break;
322 os << ", font size = ";
323 switch(_fontSize) {
324 case small:
325 os << "small";
326 break;
327 case medium:
328 os << "medium";
329 break;
330 case large:
331 os << "large";
332 break;