00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "PreCompiled.h"
00024
00025 #ifndef _PreComp_
00026 # ifdef FC_OS_WIN32
00027 # include <windows.h>
00028 # undef min
00029 # undef max
00030 # endif
00031 # ifdef FC_OS_MACOSX
00032 # include <OpenGL/gl.h>
00033 # else
00034 # include <GL/gl.h>
00035 # endif
00036 # include <cfloat>
00037 # include <algorithm>
00038 # include <QFontMetrics>
00039 # include <QGLWidget>
00040 # include <QPainter>
00041 # include <QPen>
00042 # include <Inventor/SoPrimitiveVertex.h>
00043 # include <Inventor/actions/SoGLRenderAction.h>
00044 # include <Inventor/misc/SoState.h>
00045 # include <math.h>
00046 #endif
00047
00048 #include <Inventor/elements/SoFontNameElement.h>
00049 #include <Inventor/elements/SoFontSizeElement.h>
00050 #include <Inventor/elements/SoModelMatrixElement.h>
00051 #include <Inventor/elements/SoProjectionMatrixElement.h>
00052 #include <Inventor/elements/SoViewingMatrixElement.h>
00053 #include <Inventor/elements/SoViewVolumeElement.h>
00054 #include <Inventor/elements/SoViewportRegionElement.h>
00055
00056 #include "SoDatumLabel.h"
00057 #include <Gui/BitmapFactory.h>
00058
00059 using namespace SketcherGui;
00060
00061
00062
00063 SO_NODE_SOURCE(SoDatumLabel);
00064
00065 void SoDatumLabel::initClass()
00066 {
00067 SO_NODE_INIT_CLASS(SoDatumLabel, SoShape, "Shape");
00068 }
00069
00070
00071 SoDatumLabel::SoDatumLabel()
00072 {
00073 SO_NODE_CONSTRUCTOR(SoDatumLabel);
00074 SO_NODE_ADD_FIELD(string, (""));
00075 SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
00076 SO_NODE_ADD_FIELD(name, ("Helvetica"));
00077 SO_NODE_ADD_FIELD(size, (12));
00078
00079 this->bbx = 0;
00080 this->bby = 0;
00081 }
00082
00083 void SoDatumLabel::drawImage()
00084 {
00085 const SbString* s = string.getValues(0);
00086 int num = string.getNum();
00087 if (num == 0) {
00088 this->image = SoSFImage();
00089 return;
00090 }
00091
00092 QFont font(QString::fromAscii(name.getValue()), size.getValue());
00093 QFontMetrics fm(font);
00094 QString str = QString::fromUtf8(s[0].getString());
00095 int w = fm.width(str);
00096 int h = fm.height();
00097
00098
00099 if (!w) {
00100 this->image = SoSFImage();
00101 return;
00102 }
00103
00104 const SbColor& t = textColor.getValue();
00105 QColor front;
00106 front.setRgbF(t[0],t[1], t[2]);
00107
00108 QImage image(w, h,QImage::Format_ARGB32_Premultiplied);
00109 image.fill(0x00000000);
00110
00111 QPainter painter(&image);
00112 painter.setRenderHint(QPainter::Antialiasing);
00113
00114 painter.setPen(front);
00115 painter.setFont(font);
00116 painter.drawText(0,0,w,h, Qt::AlignLeft , str);
00117 painter.end();
00118
00119 SoSFImage sfimage;
00120 Gui::BitmapFactory().convert(image, sfimage);
00121 this->image = sfimage;
00122 }
00123
00124 void SoDatumLabel::computeBBox(SoAction *action, SbBox3f &box, SbVec3f ¢er)
00125 {
00126 SbVec2s size;
00127 int nc;
00128
00129 const unsigned char * dataptr = this->image.getValue(size, nc);
00130 if (dataptr == NULL) {
00131 box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
00132 center.setValue(0.0f,0.0f,0.0f);
00133 return;
00134 }
00135
00136 float srcw = size[0];
00137 float srch = size[1];
00138
00139 float height, width;
00140
00141 if(action->getTypeId() == SoGLRenderAction::getClassTypeId()) {
00142
00143 SoState *state = action->getState();
00144 float srcw = size[0];
00145 float srch = size[1];
00146
00147 const SbViewVolume & vv = SoViewVolumeElement::get(state);
00148 float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.5f);
00149
00150 float aspectRatio = (float) srcw / (float) srch;
00151 float height = scale / (float) srch;
00152 float width = aspectRatio * (float) height;
00153
00154
00155 this->bbx = width;
00156 this->bby = height;
00157 } else {
00158
00159 width = this->bbx;
00160 height = this->bby;
00161 }
00162
00163 SbVec3f min (-width / 2, -height / 2, 0.f);
00164 SbVec3f max (width / 2, height / 2, 0.f);
00165 box.setBounds(min, max);
00166 center.setValue(0.f,0.f,0.f);
00167 }
00168
00169 void SoDatumLabel::generatePrimitives(SoAction * action)
00170 {
00171
00172 SbVec2s size;
00173 int nc;
00174
00175 const unsigned char * dataptr = this->image.getValue(size, nc);
00176 if (dataptr == NULL)
00177 return;
00178
00179 float width, height;
00180
00181 if (action->getTypeId() == SoGLRenderAction::getClassTypeId()) {
00182
00183 SoState *state = action->getState();
00184 float srcw = size[0];
00185 float srch = size[1];
00186
00187 const SbViewVolume & vv = SoViewVolumeElement::get(state);
00188 float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.5f);
00189
00190 float aspectRatio = (float) srcw / (float) srch;
00191 float height = scale / (float) srch;
00192 float width = aspectRatio * (float) height;
00193
00194
00195 this->bbx = width;
00196 this->bby = height;
00197 } else {
00198
00199 width = this->bbx;
00200 height = this->bby;
00201 }
00202
00203 SoPrimitiveVertex pv;
00204
00205 beginShape(action, QUADS);
00206
00207 pv.setNormal( SbVec3f(0.f, 0.f, 1.f) );
00208
00209
00210 pv.setPoint( SbVec3f(-width / 2, height / 2, 0.f) );
00211 shapeVertex(&pv);
00212
00213 pv.setPoint( SbVec3f(-width / 2, -height / 2, 0.f) );
00214 shapeVertex(&pv);
00215
00216 pv.setPoint( SbVec3f(width / 2, -height / 2, 0.f) );
00217 shapeVertex(&pv);
00218
00219 pv.setPoint( SbVec3f(width / 2, height / 2, 0.f) );
00220 shapeVertex(&pv);
00221
00222 endShape();
00223 }
00224
00225 void SoDatumLabel::GLRender(SoGLRenderAction * action)
00226 {
00227 SoState *state = action->getState();
00228 if (!shouldGLRender(action))
00229 return;
00230 if (action->handleTransparency(true))
00231 return;
00232 drawImage();
00233
00234 SbVec2s size;
00235 int nc;
00236 const unsigned char * dataptr = this->image.getValue(size, nc);
00237 if (dataptr == NULL) return;
00238
00239 int srcw = size[0];
00240 int srch = size[1];
00241
00242 state->push();
00243
00244 glPixelStorei(GL_UNPACK_ROW_LENGTH, srcw);
00245 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00246
00247 glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
00248 glDisable(GL_LIGHTING);
00249 glEnable(GL_DEPTH_TEST);
00250 glEnable(GL_TEXTURE_2D);
00251 glEnable(GL_BLEND);
00252
00253 GLuint myTexture;
00254
00255 glGenTextures(1, &myTexture);
00256
00257 glBindTexture(GL_TEXTURE_2D, myTexture);
00258
00259 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00260 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00261
00262 glTexImage2D(GL_TEXTURE_2D, 0, nc, srcw, srch, 0, GL_RGBA, GL_UNSIGNED_BYTE,(const GLvoid*) dataptr);
00263
00264 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00265
00266 const SbViewVolume & vv = SoViewVolumeElement::get(state);
00267 float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.4f);
00268
00269 float aspectRatio = (float) srcw / (float) srch;
00270 float height = scale / (float) srch;
00271 float width = aspectRatio * (float) height;
00272
00273 this->bbx = width;
00274 this->bby = height;
00275 glBegin(GL_QUADS);
00276 glColor3f(1.f, 1.f, 1.f);
00277 glTexCoord2f(0.f, 1.f); glVertex2f(-width/ 2, height / 2);
00278 glTexCoord2f(0.f, 0.f); glVertex2f(-width / 2,-height / 2);
00279 glTexCoord2f(1.f, 0.f); glVertex2f( width/ 2,-height / 2);
00280 glTexCoord2f(1.f, 1.f); glVertex2f( width / 2, height / 2);
00281
00282 glEnd();
00283
00284
00285 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00286 glPopAttrib();
00287 state->pop();
00288 }