FreeCAD

Форк
0
/
SoTextLabel.cpp 
488 строк · 14.8 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2009 Werner Mayer <wmayer[at]users.sourceforge.net>     *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#ifndef _PreComp_
26
# ifdef FC_OS_WIN32
27
# include <windows.h>
28
# endif
29
# ifdef FC_OS_MACOSX
30
# include <OpenGL/gl.h>
31
# else
32
# include <GL/gl.h>
33
# endif
34
# include <cfloat>
35
# include <QFontMetrics>
36
# include <QPainter>
37
# include <QPen>
38
# include <Inventor/actions/SoGLRenderAction.h>
39
# include <Inventor/bundles/SoMaterialBundle.h>
40
# include <Inventor/elements/SoLazyElement.h>
41
# include <Inventor/misc/SoState.h>
42
#endif
43

44
#include <Inventor/C/basic.h>
45
#include <Inventor/draggers/SoTranslate2Dragger.h>
46
#include <Inventor/elements/SoCullElement.h>
47
#include <Inventor/elements/SoFontNameElement.h>
48
#include <Inventor/elements/SoGLTextureEnabledElement.h>
49
#include <Inventor/elements/SoModelMatrixElement.h>
50
#include <Inventor/elements/SoProjectionMatrixElement.h>
51
#include <Inventor/elements/SoViewingMatrixElement.h>
52
#include <Inventor/elements/SoViewportRegionElement.h>
53
#include <Inventor/elements/SoViewVolumeElement.h>
54

55
#if COIN_MAJOR_VERSION > 3
56
#include <Inventor/elements/SoMultiTextureEnabledElement.h>
57
#else
58
#include <Inventor/elements/SoGLTexture3EnabledElement.h>
59
#endif
60

61
#include <QtOpenGL.h>
62

63
#include "SoTextLabel.h"
64
#include "BitmapFactory.h"
65
#include "SoFCInteractiveElement.h"
66
#include "Tools.h"
67

68

69
using namespace Gui;
70

71
/*!
72
\code
73

74
s="""
75
  #Inventor V2.1 ascii
76

77
  Annotation {
78
    Translation { translation 4 0 0 }
79
    FontStyle {
80
        size 20
81
        style BOLD
82
    }
83
    BaseColor {
84
        rgb 0.0 0.0 0.0
85
    }
86

87

88
    SoTextLabel { string ["Text label", "Second line"] backgroundColor 1.0 0.447059 0.337255}
89
  }
90
"""
91

92
App.ActiveDocument.addObject("App::InventorObject","iv").Buffer=s
93

94
\endcode
95
*/
96

97
SO_NODE_SOURCE(SoTextLabel)
98

99
void SoTextLabel::initClass()
100
{
101
    SO_NODE_INIT_CLASS(SoTextLabel, SoText2, "Text2");
102
}
103

104
SoTextLabel::SoTextLabel()
105
{
106
    SO_NODE_CONSTRUCTOR(SoTextLabel);
107
    SO_NODE_ADD_FIELD(backgroundColor, (SbVec3f(1.0f,1.0f,1.0f)));
108
    SO_NODE_ADD_FIELD(background, (true));
109
    SO_NODE_ADD_FIELD(frameSize, (10.0f));
110
}
111

112
/**
113
 * Renders the label.
114
 */
115
void SoTextLabel::GLRender(SoGLRenderAction *action)
116
{
117
    if (!this->shouldGLRender(action))
118
        return;
119

120
    // only draw text without background
121
    if (!this->background.getValue()) {
122
        inherited::GLRender(action);
123
        return;
124
    }
125

126
    SoState * state = action->getState();
127

128
    state->push();
129
    SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
130

131
    SbBox3f box;
132
    SbVec3f center;
133
    this->computeBBox(action, box, center);
134

135
    if (!SoCullElement::cullTest(state, box, true)) {
136
        SoMaterialBundle mb(action);
137
        mb.sendFirst();
138
        const SbMatrix & mat = SoModelMatrixElement::get(state);
139
        const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) *
140
                                       SoProjectionMatrixElement::get(state));
141
        const SbViewportRegion & vp = SoViewportRegionElement::get(state);
142
        SbVec2s vpsize = vp.getViewportSizePixels();
143

144
        // font stuff
145
        SbName fontname = SoFontNameElement::get(state);
146
        int lines = this->string.getNum();
147

148
        // get left bottom corner of the label
149
        SbVec3f nilpoint(0.0f, 0.0f, 0.0f);
150
        projmatrix.multVecMatrix(nilpoint, nilpoint);
151
        nilpoint[0] = (nilpoint[0] + 1.0f) * 0.5f * vpsize[0];
152
        nilpoint[1] = (nilpoint[1] + 1.0f) * 0.5f * vpsize[1];
153

154
        // Unfortunately, the size of the label is stored in the pimpl class of
155
        // SoText2 which cannot be accessed directly. However, there is a trick
156
        // to get the required information: set model, viewing and projection
157
        // matrix to the identity matrix and also view volume to some default
158
        // values. SoText2::computeBBox() then calls SoText2P::getQuad which
159
        // returns the sizes in form of the bounding box. These values can be
160
        // reverse-engineered to get width and height.
161
        state->push();
162
        SoModelMatrixElement::set(state,this,SbMatrix::identity());
163
        SoViewingMatrixElement::set(state,this,SbMatrix::identity());
164
        SoProjectionMatrixElement::set(state,this,SbMatrix::identity());
165
        SbViewVolume vv;
166
        vv.ortho(-1,1,-1,1,-1,1);
167
        SoViewVolumeElement::set(state,this,vv);
168

169
        SbBox3f box;
170
        SbVec3f center;
171
        this->computeBBox(action, box, center);
172
        state->pop();
173

174
        float xmin,ymin,zmin,xmax,ymax,zmax;
175
        box.getBounds(xmin,ymin,zmin,xmax,ymax,zmax);
176
        SbVec3f v0(xmin,ymax,zmax);
177
        SbVec3f v1(xmax,ymax,zmax);
178
        SbVec3f v2(xmax,ymin,zmax);
179
        SbVec3f v3(xmin,ymin,zmax);
180
        vv.projectToScreen(v0,v0);
181
        vv.projectToScreen(v1,v1);
182
        vv.projectToScreen(v2,v2);
183
        vv.projectToScreen(v3,v3);
184

185
        float width,height;
186
        width  = (v1[0]-v0[0])*vpsize[0];
187
        height = (v1[1]-v3[1])*vpsize[1];
188
        switch (this->justification.getValue()) {
189
        case SoText2::RIGHT:
190
            nilpoint[0] -= width;
191
            break;
192
        case SoText2::CENTER:
193
            nilpoint[0] -= 0.5f*width;
194
            break;
195
        default:
196
            break;
197
        }
198

199
        if (lines > 1) {
200
            nilpoint[1] -= (float(lines-1)/(float)lines*height);
201
        }
202

203
        SbVec3f toppoint = nilpoint;
204
        toppoint[0] += width;
205
        toppoint[1] += height;
206

207
        // Set new state.
208
        glMatrixMode(GL_MODELVIEW);
209
        glPushMatrix();
210
        glLoadIdentity();
211
        glMatrixMode(GL_PROJECTION);
212
        glPushMatrix();
213
        glLoadIdentity();
214
        glOrtho(0, vpsize[0], 0, vpsize[1], -1.0f, 1.0f);
215
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
216

217
        state->push();
218

219
        // disable textures for all units
220
        SoGLTextureEnabledElement::set(state, this, false);
221
#if COIN_MAJOR_VERSION > 3
222
        SoMultiTextureEnabledElement::set(state, this, false);
223
#else
224
        SoGLTexture3EnabledElement::set(state, this, false);
225
#endif
226

227
        glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
228
        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
229

230
        // color and frame size
231
        SbColor color = this->backgroundColor.getValue();
232
        float fs = this->frameSize.getValue();
233

234
        // draw background
235
        glColor3f(color[0], color[1], color[2]);
236
        glBegin(GL_QUADS);
237
        glVertex3f(nilpoint[0]-fs,nilpoint[1]-fs,0.0f);
238
        glVertex3f(toppoint[0]+fs,nilpoint[1]-fs,0.0f);
239
        glVertex3f(toppoint[0]+fs,toppoint[1]+fs,0.0f);
240
        glVertex3f(nilpoint[0]-fs,toppoint[1]+fs,0.0f);
241
        glEnd();
242

243
        // pop old state
244
        glPopClientAttrib();
245
        glPopAttrib();
246
        state->pop();
247

248
        glPixelStorei(GL_UNPACK_ALIGNMENT,4);
249
        // Pop old GL matrix state.
250
        glMatrixMode(GL_PROJECTION);
251
        glPopMatrix();
252
        glMatrixMode(GL_MODELVIEW);
253
        glPopMatrix();
254
    }
255

256
    state->pop();
257

258
    inherited::GLRender(action);
259
}
260

261
// ------------------------------------------------------
262

263
SO_NODE_SOURCE(SoColorBarLabel)
264

265
void SoColorBarLabel::initClass()
266
{
267
    SO_NODE_INIT_CLASS(SoColorBarLabel, SoText2, "Text2");
268
}
269

270
SoColorBarLabel::SoColorBarLabel()
271
{
272
    SO_NODE_CONSTRUCTOR(SoColorBarLabel);
273
}
274

275
void SoColorBarLabel::computeBBox(SoAction * action, SbBox3f & box, SbVec3f & center)
276
{
277
    inherited::computeBBox(action, box, center);
278
    if (!box.hasVolume()) {
279
        SbViewVolume vv = SoViewVolumeElement::get(action->getState());
280
        // workaround for https://github.com/coin3d/coin/issues/417:
281
        // extend by 2 percent
282
        vv.scaleWidth(1.02f);
283
        SoViewVolumeElement::set(action->getState(), this, vv);
284
        inherited::computeBBox(action, box, center);
285
    }
286
}
287

288
// ------------------------------------------------------
289

290
SO_NODE_SOURCE(SoStringLabel)
291

292
void SoStringLabel::initClass()
293
{
294
    SO_NODE_INIT_CLASS(SoStringLabel, SoNode, "Node");
295
}
296

297
SoStringLabel::SoStringLabel()
298
{
299
    SO_NODE_CONSTRUCTOR(SoStringLabel);
300
    SO_NODE_ADD_FIELD(string, (""));
301
    SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
302
    SO_NODE_ADD_FIELD(name, ("Helvetica"));
303
    SO_NODE_ADD_FIELD(size, (12));
304
}
305

306
/**
307
 * Renders the open edges only.
308
 */
309
void SoStringLabel::GLRender(SoGLRenderAction *action)
310
{
311
    QtGLWidget* window;
312
    SoState * state = action->getState();
313
    state->push();
314
    SoLazyElement::setLightModel(state, SoLazyElement::BASE_COLOR);
315
    SoGLWidgetElement::get(state, window);
316
    if (!window) {
317
        state->pop();
318
        return;
319
    }
320

321
    // Enter in 2D screen mode
322
    glMatrixMode(GL_PROJECTION);
323
    glPushMatrix();
324
    glLoadIdentity();
325
    glOrtho(-1,1,-1,1,-1,1);
326
    glMatrixMode(GL_MODELVIEW);
327
    glPushMatrix();
328
    glLoadIdentity();
329
    glPushAttrib(GL_ENABLE_BIT);
330
    glDisable(GL_DEPTH_TEST);
331
    glDisable(GL_LIGHTING);
332
    glDisable(GL_TEXTURE_2D);
333
    glEnable(GL_BLEND);
334

335
    QFont font;
336
    font.setStyleStrategy(QFont::NoAntialias);
337
    font.setFamily(QLatin1String(this->name.getValue()));
338
    font.setPixelSize(this->size.getValue());
339

340
    glBlendFunc(GL_ONE,GL_SRC_ALPHA);
341

342
    // text color
343
    SbColor color = this->textColor.getValue();
344
    glColor4f(color[0], color[1], color[2], 1);
345
    const SbMatrix & mat = SoModelMatrixElement::get(state);
346
    const SbMatrix & projmatrix = (mat * SoViewingMatrixElement::get(state) *
347
                                   SoProjectionMatrixElement::get(state));
348
    SbVec3f nil(0.0f, 0.0f, 0.0f);
349
    projmatrix.multVecMatrix(nil, nil);
350
    QStringList list;
351
    for (int i=0; i<this->string.getNum(); i++)
352
        list << QLatin1String(this->string[i].getString());
353

354
    // Leave 2D screen mode
355
    glPopAttrib();
356
    glPopMatrix();
357
    glMatrixMode(GL_PROJECTION);
358
    glPopMatrix();
359
    glMatrixMode(GL_MODELVIEW);
360

361
    state->pop();
362
}
363

364
// ------------------------------------------------------
365

366
SO_NODE_SOURCE(SoFrameLabel)
367

368
void SoFrameLabel::initClass()
369
{
370
    SO_NODE_INIT_CLASS(SoFrameLabel, SoImage, "Image");
371
}
372

373
SoFrameLabel::SoFrameLabel()
374
{
375
    SO_NODE_CONSTRUCTOR(SoFrameLabel);
376
    SO_NODE_ADD_FIELD(string, (""));
377
    SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
378
    SO_NODE_ADD_FIELD(backgroundColor, (SbVec3f(0.0f,0.333f,1.0f)));
379
    SO_NODE_ADD_FIELD(justification, (LEFT));
380
    SO_NODE_ADD_FIELD(name, ("Helvetica"));
381
    SO_NODE_ADD_FIELD(size, (12));
382
    SO_NODE_ADD_FIELD(frame, (true));
383
  //SO_NODE_ADD_FIELD(image, (SbVec2s(0,0), 0, NULL));
384
}
385

386
void SoFrameLabel::notify(SoNotList * list)
387
{
388
    SoField *f = list->getLastField();
389
    if (f == &this->string ||
390
        f == &this->textColor ||
391
        f == &this->backgroundColor ||
392
        f == &this->justification ||
393
        f == &this->name ||
394
        f == &this->size ||
395
        f == &this->frame) {
396
        drawImage();
397
    }
398
    inherited::notify(list);
399
}
400

401
void SoFrameLabel::drawImage()
402
{
403
    const SbString* s = string.getValues(0);
404
    int num = string.getNum();
405
    if (num == 0) {
406
        this->image = SoSFImage();
407
        return;
408
    }
409

410
    QFont font(QString::fromLatin1(QByteArray(name.getValue())), size.getValue());
411
    QFontMetrics fm(font);
412
    int w = 0;
413
    int h = fm.height() * num;
414
    const SbColor& b = backgroundColor.getValue();
415
    QColor brush;
416
    brush.setRgbF(b[0],b[1],b[2]);
417
    const SbColor& t = textColor.getValue();
418
    QColor front;
419
    front.setRgbF(t[0],t[1],t[2]);
420

421
    QStringList lines;
422
    for (int i=0; i<num; i++) {
423
        QString line = QString::fromUtf8(s[i].getString());
424
        w = std::max<int>(w, QtTools::horizontalAdvance(fm, line));
425
        lines << line;
426
    }
427

428
    QImage image(w+10,h+10,QImage::Format_ARGB32_Premultiplied);
429
    image.fill(0x00000000);
430
    QPainter painter(&image);
431
    painter.setRenderHint(QPainter::Antialiasing);
432

433
    SbBool drawFrame = frame.getValue();
434
    if (drawFrame) {
435
        painter.setPen(QPen(QColor(0,0,127), 2, Qt::SolidLine, Qt::RoundCap,
436
                            Qt::RoundJoin));
437
        painter.setBrush(QBrush(brush, Qt::SolidPattern));
438
        QRectF rectangle(0.0, 0.0, w+10, h+10);
439
        painter.drawRoundedRect(rectangle, 5, 5);
440
    }
441

442
    painter.setPen(front);
443

444
    Qt::Alignment align = Qt::AlignVCenter;
445
    if (justification.getValue() == 0)
446
        align = Qt::AlignVCenter | Qt::AlignLeft;
447
    else if (justification.getValue() == 1)
448
        align = Qt::AlignVCenter | Qt::AlignRight;
449
    else
450
        align = Qt::AlignVCenter | Qt::AlignHCenter;
451
    QString text = lines.join(QLatin1String("\n"));
452
    painter.setFont(font);
453
    painter.drawText(5,5,w,h,align,text);
454
    painter.end();
455

456
    SoSFImage sfimage;
457
    Gui::BitmapFactory().convert(image, sfimage);
458
    this->image = sfimage;
459
}
460

461
/**
462
 * Renders the open edges only.
463
 */
464
void SoFrameLabel::GLRender(SoGLRenderAction *action)
465
{
466
    inherited::GLRender(action);
467
}
468

469
// ------------------------------------------------------
470

471
SO_NODE_SOURCE(TranslateManip)
472

473
void
474
TranslateManip::initClass()
475
{
476
    SO_NODE_INIT_CLASS(TranslateManip, SoTransformManip,
477
                       "TransformManip");
478
}
479

480
TranslateManip::TranslateManip()
481
{
482
    SO_NODE_CONSTRUCTOR(TranslateManip);
483

484
    auto myDrag = new SoTranslate2Dragger;
485
    setDragger(myDrag);
486
}
487

488
TranslateManip::~TranslateManip() = default;
489

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.