0024057: Eliminate compiler warning C4100 in MSVC++ with warning level 4
[occt.git] / src / OpenGl / OpenGl_Text.cxx
CommitLineData
b311480e 1// Created on: 2011-07-13
2// Created by: Sergey ZERCHANINOV
a174a3c5 3// Copyright (c) 2011-2013 OPEN CASCADE SAS
b311480e 4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
5f8b738e 20#include <OpenGl_GlCore11.hxx>
2166f0fa 21#include <OpenGl_Text.hxx>
a174a3c5 22
2166f0fa 23#include <OpenGl_AspectText.hxx>
a174a3c5 24#include <OpenGl_GraphicDriver.hxx>
bf75be98 25#include <OpenGl_Workspace.hxx>
2166f0fa 26
a174a3c5 27#include <Font_FontMgr.hxx>
28#include <TCollection_HAsciiString.hxx>
29
30#ifdef HAVE_CONFIG_H
31 #include <config.h>
32#endif
2166f0fa 33
a174a3c5 34#ifdef HAVE_GL2PS
35 #include <gl2ps.h>
36#endif
37
38namespace
2166f0fa 39{
a174a3c5 40 static const GLdouble THE_IDENTITY_MATRIX[4][4] =
41 {
42 {1.,0.,0.,0.},
43 {0.,1.,0.,0.},
44 {0.,0.,1.,0.},
45 {0.,0.,0.,1.}
46 };
47
48#ifdef HAVE_GL2PS
49 static char const* TheFamily[] = {"Helvetica", "Courier", "Times"};
50 static char const* TheItalic[] = {"Oblique", "Oblique", "Italic"};
51 static char const* TheBase[] = {"", "", "-Roman"};
52
53 //! Convert font name used for rendering to some "good" font names
54 //! that produce good vector text.
55 static void getGL2PSFontName (const char* theSrcFont,
56 char* thePsFont)
57 {
58 if (strstr (theSrcFont, "Symbol"))
59 {
60 sprintf (thePsFont, "%s", "Symbol");
61 return;
62 }
63 else if (strstr (theSrcFont, "ZapfDingbats"))
64 {
65 sprintf (thePsFont, "%s", "WingDings");
66 return;
67 }
2166f0fa 68
a174a3c5 69 int aFontId = 0;
70 bool isBold = false;
71 bool isItalic = false;
72 if (strstr (theSrcFont, "Courier"))
73 {
74 aFontId = 1;
75 }
76 else if (strstr (theSrcFont, "Times"))
77 {
78 aFontId = 2;
79 }
2166f0fa 80
a174a3c5 81 if (strstr (theSrcFont, "Bold"))
82 {
83 isBold = true;
84 }
85 if (strstr (theSrcFont, "Italic")
86 || strstr (theSrcFont, "Oblique"))
87 {
88 isItalic = true;
89 }
2166f0fa 90
a174a3c5 91 if (isBold)
92 {
a174a3c5 93 if (isItalic)
94 {
8b224a09 95 sprintf (thePsFont, "%s-Bold%s", TheFamily[aFontId], TheItalic[aFontId]);
96 }
97 else
98 {
99 sprintf (thePsFont, "%s-Bold", TheFamily[aFontId]);
a174a3c5 100 }
101 }
102 else if (isItalic)
103 {
104 sprintf (thePsFont, "%s-%s", TheFamily[aFontId], TheItalic[aFontId]);
105 }
106 else
107 {
108 sprintf (thePsFont, "%s%s", TheFamily[aFontId], TheBase[aFontId]);
109 }
110 }
2166f0fa 111
a174a3c5 112 static void exportText (const NCollection_String& theText,
113 const Standard_Boolean theIs2d,
114 const OpenGl_AspectText& theAspect,
115 const Standard_Integer theHeight)
116 {
2166f0fa 117
a174a3c5 118 char aPsFont[64];
119 getGL2PSFontName (theAspect.FontName().ToCString(), aPsFont);
2166f0fa 120
a174a3c5 121 if (theIs2d)
122 {
123 glRasterPos2f (0.0f, 0.0f);
124 }
125 else
126 {
127 glRasterPos3f (0.0f, 0.0f, 0.0f);
128 }
129
130 GLubyte aZero = 0;
131 glBitmap (1, 1, 0, 0, 0, 0, &aZero);
132
133 // Standard GL2PS's alignment isn't used, because it doesn't work correctly
134 // for all formats, therefore alignment is calculated manually relative
135 // to the bottom-left corner, which corresponds to the GL2PS_TEXT_BL value
136 gl2psTextOpt (theText.ToCString(), aPsFont, theHeight, GL2PS_TEXT_BL, theAspect.Angle());
137 }
138#endif
139
140};
141
142// =======================================================================
143// function : OpenGl_Text
144// purpose :
145// =======================================================================
146OpenGl_Text::OpenGl_Text()
147: myWinX (0.0f),
148 myWinY (0.0f),
149 myWinZ (0.0f),
150 myScaleHeight (1.0f),
151 myPoint (0.0f, 0.0f, 0.0f),
152 myIs2d (false)
153{
154 myParams.Height = 10;
155 myParams.HAlign = Graphic3d_HTA_LEFT;
156 myParams.VAlign = Graphic3d_VTA_BOTTOM;
2166f0fa
SK
157}
158
a174a3c5 159// =======================================================================
160// function : OpenGl_Text
161// purpose :
162// =======================================================================
163OpenGl_Text::OpenGl_Text (const TCollection_ExtendedString& theText,
164 const OpenGl_Vec3& thePoint,
165 const OpenGl_TextParam& theParams)
166: myWinX (0.0f),
167 myWinY (0.0f),
168 myWinZ (0.0f),
169 myScaleHeight (1.0f),
170 myExportHeight (1.0f),
171 myParams (theParams),
172 myString ((Standard_Utf16Char* )theText.ToExtString()),
173 myPoint (thePoint),
174 myIs2d (false)
175{
176 //
177}
2166f0fa 178
a174a3c5 179// =======================================================================
180// function : SetPosition
181// purpose :
182// =======================================================================
183void OpenGl_Text::SetPosition (const OpenGl_Vec3& thePoint)
2166f0fa 184{
a174a3c5 185 myPoint = thePoint;
2166f0fa
SK
186}
187
a174a3c5 188// =======================================================================
189// function : SetFontSize
190// purpose :
191// =======================================================================
192void OpenGl_Text::SetFontSize (const Handle(OpenGl_Context)& theCtx,
193 const Standard_Integer theFontSize)
194{
195 if (myParams.Height != theFontSize)
196 {
197 Release (theCtx);
198 }
199 myParams.Height = theFontSize;
200}
201
202// =======================================================================
203// function : Init
204// purpose :
205// =======================================================================
206void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
207 const Standard_Utf8Char* theText,
208 const OpenGl_Vec3& thePoint)
209{
210 releaseVbos (theCtx);
211 myIs2d = false;
212 myPoint = thePoint;
213 myString.FromUnicode (theText);
214}
215
216// =======================================================================
217// function : Init
218// purpose :
219// =======================================================================
220void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
221 const Standard_Utf8Char* theText,
222 const OpenGl_Vec3& thePoint,
223 const OpenGl_TextParam& theParams)
224{
225 if (myParams.Height != theParams.Height)
226 {
227 Release (theCtx);
228 }
229 else
230 {
231 releaseVbos (theCtx);
232 }
233 myIs2d = false;
234 myParams = theParams;
235 myPoint = thePoint;
236 myString.FromUnicode (theText);
237}
2166f0fa 238
a174a3c5 239// =======================================================================
240// function : Init
241// purpose :
242// =======================================================================
243void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
244 const TCollection_ExtendedString& theText,
245 const OpenGl_Vec2& thePoint,
246 const OpenGl_TextParam& theParams)
2166f0fa 247{
a174a3c5 248 if (myParams.Height != theParams.Height)
249 {
250 Release (theCtx);
251 }
252 else
253 {
254 releaseVbos (theCtx);
255 }
256 myIs2d = true;
257 myParams = theParams;
258 myPoint.xy() = thePoint;
259 myPoint.z() = 0.0f;
260 myString.FromUnicode ((Standard_Utf16Char* )theText.ToExtString());
261}
262
263// =======================================================================
264// function : ~OpenGl_Text
265// purpose :
266// =======================================================================
267OpenGl_Text::~OpenGl_Text()
268{
269 //
270}
271
272// =======================================================================
273// function : releaseVbos
274// purpose :
275// =======================================================================
276void OpenGl_Text::releaseVbos (const Handle(OpenGl_Context)& theCtx)
277{
278 for (Standard_Integer anIter = 0; anIter < myVertsVbo.Length(); ++anIter)
279 {
280 Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.ChangeValue (anIter);
281 Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.ChangeValue (anIter);
282
283 if (!theCtx.IsNull())
284 {
285 theCtx->DelayedRelease (aVerts);
286 theCtx->DelayedRelease (aTCrds);
287 }
288 aVerts.Nullify();
289 aTCrds.Nullify();
290 }
291 myTextures.Clear();
292 myVertsVbo.Clear();
293 myTCrdsVbo.Clear();
294 myVertsArray.Clear();
295 myTCrdsArray.Clear();
296}
297
298// =======================================================================
299// function : Release
300// purpose :
301// =======================================================================
302void OpenGl_Text::Release (const Handle(OpenGl_Context)& theCtx)
303{
304 releaseVbos (theCtx);
305 if (!myFont.IsNull())
306 {
307 Handle(OpenGl_Context) aCtx = theCtx;
308 const TCollection_AsciiString aKey = myFont->ResourceKey();
309 myFont.Nullify();
310 aCtx->ReleaseResource (aKey, Standard_True);
311 }
312}
313
314// =======================================================================
315// function : StringSize
316// purpose :
317// =======================================================================
318void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
319 const NCollection_String& theText,
320 const OpenGl_AspectText& theTextAspect,
321 const OpenGl_TextParam& theParams,
322 Standard_ShortReal& theWidth,
323 Standard_ShortReal& theAscent,
324 Standard_ShortReal& theDescent)
325{
326 theWidth = 0.0f;
327 theAscent = 0.0f;
328 theDescent = 0.0f;
329 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, theParams.Height);
330 Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, theParams.Height, aFontKey);
331 if (aFont.IsNull() || !aFont->IsValid())
332 {
2166f0fa 333 return;
a174a3c5 334 }
335
336 theAscent = aFont->Ascender();
337 theDescent = aFont->Descender();
338
339 GLfloat aWidth = 0.0f;
340 for (NCollection_Utf8Iter anIter = theText.Iterator(); *anIter != 0;)
341 {
342 const Standard_Utf32Char aCharThis = *anIter;
343 const Standard_Utf32Char aCharNext = *++anIter;
344
345 if (aCharThis == '\x0D' // CR (carriage return)
346 || aCharThis == '\a' // BEL (alarm)
347 || aCharThis == '\f' // FF (form feed) NP (new page)
348 || aCharThis == '\b' // BS (backspace)
349 || aCharThis == '\v') // VT (vertical tab)
350 {
351 continue; // skip unsupported carriage control codes
352 }
353 else if (aCharThis == '\x0A') // LF (line feed, new line)
354 {
355 theWidth = Max (theWidth, aWidth);
356 aWidth = 0.0f;
357 continue;
358 }
359 else if (aCharThis == ' ')
360 {
361 aWidth += aFont->AdvanceX (aCharThis, aCharNext);
362 continue;
363 }
364 else if (aCharThis == '\t')
365 {
366 aWidth += aFont->AdvanceX (' ', aCharNext) * 8.0f;
367 continue;
368 }
369
370 aWidth += aFont->AdvanceX (aCharThis, aCharNext);
371 }
372 theWidth = Max (theWidth, aWidth);
373
374 Handle(OpenGl_Context) aCtx = theCtx;
375 aFont.Nullify();
376 aCtx->ReleaseResource (aFontKey, Standard_True);
377}
378
379// =======================================================================
380// function : Render
381// purpose :
382// =======================================================================
383void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
384{
a174a3c5 385 const OpenGl_AspectText* aTextAspect = theWorkspace->AspectText (Standard_True);
386 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
387
388 // use highlight color or colors from aspect
389 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
390 {
391 render (theWorkspace->PrinterContext(),
392 theWorkspace->GetGlContext(),
393 *aTextAspect,
394 *theWorkspace->HighlightColor,
395 *theWorkspace->HighlightColor);
396 }
397 else
398 {
399 render (theWorkspace->PrinterContext(),
400 theWorkspace->GetGlContext(),
401 *aTextAspect,
402 aTextAspect->Color(),
403 aTextAspect->SubtitleColor());
404 }
2166f0fa 405
a174a3c5 406 // restore aspects
407 if (!aPrevTexture.IsNull())
408 {
409 theWorkspace->EnableTexture (aPrevTexture);
410 }
411}
2166f0fa 412
a174a3c5 413// =======================================================================
414// function : Render
415// purpose :
416// =======================================================================
417void OpenGl_Text::Render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
418 const Handle(OpenGl_Context)& theCtx,
419 const OpenGl_AspectText& theTextAspect) const
420{
421 render (thePrintCtx, theCtx, theTextAspect, theTextAspect.Color(), theTextAspect.SubtitleColor());
422}
2166f0fa 423
a174a3c5 424// =======================================================================
425// function : setupMatrix
426// purpose :
427// =======================================================================
428void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
35e08fe8 429 const Handle(OpenGl_Context)& /*theCtx*/,
a174a3c5 430 const OpenGl_AspectText& theTextAspect,
431 const OpenGl_Vec3 theDVec) const
432{
433 // setup matrix
434 if (myIs2d)
bf75be98 435 {
a174a3c5 436 glLoadIdentity();
437 glTranslatef (myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.0f);
438 glRotatef (180.0f, 1.0f, 0.0f, 0.0f);
2166f0fa
SK
439 }
440 else
441 {
a174a3c5 442 // align coordinates to the nearest integer
443 // to avoid extra interpolation issues
444 GLdouble anObjX, anObjY, anObjZ;
445 gluUnProject (std::floor (myWinX + (GLdouble )theDVec.x()),
446 std::floor (myWinY + (GLdouble )theDVec.y()),
447 myWinZ + (GLdouble )theDVec.z(),
448 (GLdouble* )THE_IDENTITY_MATRIX, myProjMatrix, myViewport,
449 &anObjX, &anObjY, &anObjZ);
450
451 glLoadIdentity();
452 glTranslated (anObjX, anObjY, anObjZ);
453 glRotated (theTextAspect.Angle(), 0.0, 0.0, 1.0);
454 if (!theTextAspect.IsZoomable())
455 {
456 #ifdef _WIN32
457 // if the context has assigned printer context, use it's parameters
458 if (!thePrintCtx.IsNull())
459 {
460 // get printing scaling in x and y dimensions
461 GLfloat aTextScalex = 1.0f, aTextScaley = 1.0f;
462 thePrintCtx->GetScale (aTextScalex, aTextScaley);
463
464 // text should be scaled in all directions with same
465 // factor to save its proportions, so use height (y) scaling
466 // as it is better for keeping text/3d graphics proportions
467 glScalef (aTextScaley, aTextScaley, aTextScaley);
468 }
469 #endif
470 glScaled (myScaleHeight, myScaleHeight, myScaleHeight);
471 }
472 }
473}
474
475// =======================================================================
476// function : drawText
477// purpose :
478// =======================================================================
35e08fe8 479
480void OpenGl_Text::drawText (const Handle(OpenGl_PrinterContext)& ,
a174a3c5 481 const Handle(OpenGl_Context)& theCtx,
35e08fe8 482 #ifdef HAVE_GL2PS
a174a3c5 483 const OpenGl_AspectText& theTextAspect) const
35e08fe8 484 #else
485 const OpenGl_AspectText& ) const
486 #endif
a174a3c5 487{
488#ifdef HAVE_GL2PS
489 if (theCtx->IsFeedback())
490 {
491 // position of the text and alignment is calculated by transformation matrix
492 exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
493 return;
2166f0fa 494 }
a174a3c5 495#endif
2166f0fa 496
a174a3c5 497 if (myVertsVbo.Length() == myTextures.Length())
2166f0fa 498 {
a174a3c5 499 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
500 {
501 const GLuint aTexId = myTextures.Value (anIter);
502 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
503 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
504 aVerts->BindFixed (theCtx, GL_VERTEX_ARRAY);
505 aTCrds->BindFixed (theCtx, GL_TEXTURE_COORD_ARRAY);
506 glBindTexture (GL_TEXTURE_2D, aTexId);
507
508 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
509
510 glBindTexture (GL_TEXTURE_2D, 0);
27583309 511 aTCrds->UnbindFixed (theCtx, GL_TEXTURE_COORD_ARRAY);
a174a3c5 512 aVerts->UnbindFixed (theCtx, GL_VERTEX_ARRAY);
513 }
2166f0fa 514 }
a174a3c5 515 else if (myVertsArray.Length() == myTextures.Length())
516 {
517 glEnableClientState (GL_VERTEX_ARRAY);
518 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
519 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
520 {
521 const GLuint aTexId = myTextures.Value (anIter);
522 const Handle(OpenGl_Vec2Array)& aVerts = myVertsArray.Value (anIter);
523 const Handle(OpenGl_Vec2Array)& aTCrds = myTCrdsArray.Value (anIter);
524
525 glVertexPointer (2, GL_FLOAT, 0, (GLfloat* )&aVerts->First());
526 glTexCoordPointer (2, GL_FLOAT, 0, (GLfloat* )&aTCrds->First());
527 glBindTexture (GL_TEXTURE_2D, aTexId);
2166f0fa 528
a174a3c5 529 glDrawArrays (GL_TRIANGLES, 0, aVerts->Length());
2166f0fa 530
a174a3c5 531 glBindTexture (GL_TEXTURE_2D, 0);
532 }
533 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
534 glDisableClientState (GL_VERTEX_ARRAY);
535 }
536}
2166f0fa 537
a174a3c5 538// =======================================================================
539// function : FontKey
540// purpose :
541// =======================================================================
542TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
543 const Standard_Integer theHeight)
544{
545 const Font_FontAspect anAspect = (theAspect.FontAspect() != Font_FA_Undefined) ? theAspect.FontAspect() : Font_FA_Regular;
546 return theAspect.FontName()
547 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
548 + TCollection_AsciiString(":") + theHeight;
549}
550
551// =======================================================================
552// function : FindFont
553// purpose :
554// =======================================================================
555Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
556 const OpenGl_AspectText& theAspect,
557 const Standard_Integer theHeight,
558 const TCollection_AsciiString theKey)
559{
560 Handle(OpenGl_Font) aFont;
561 if (theHeight < 2)
2166f0fa 562 {
a174a3c5 563 return aFont; // invalid parameters
564 }
2166f0fa 565
a174a3c5 566 if (!theCtx->GetResource (theKey, aFont))
567 {
568 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
569 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.FontName());
570 const Font_FontAspect anAspect = (theAspect.FontAspect() != Font_FA_Undefined) ? theAspect.FontAspect() : Font_FA_Regular;
571 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
572 if (aRequestedFont.IsNull())
2166f0fa 573 {
a174a3c5 574 return aFont;
575 }
576
577 Handle(Font_FTFont) aFontFt = new Font_FTFont (NULL);
578 if (!aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight))
579 {
580 return aFont;
581 }
582
583 Handle(OpenGl_Context) aCtx = theCtx;
584 glPushAttrib (GL_TEXTURE_BIT);
585 aFont = new OpenGl_Font (aFontFt, theKey);
586 if (!aFont->Init (aCtx))
587 {
588 //glPopAttrib();
589 //return aFont; // out of resources?
590 }
591 glPopAttrib(); // texture bit
592
593 aCtx->ShareResource (theKey, aFont);
594 }
595 return aFont;
596}
597
598// =======================================================================
599// function : render
600// purpose :
601// =======================================================================
602void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
603 const Handle(OpenGl_Context)& theCtx,
604 const OpenGl_AspectText& theTextAspect,
605 const TEL_COLOUR& theColorText,
606 const TEL_COLOUR& theColorSubs) const
607{
608 if (myString.IsEmpty())
609 {
610 return;
611 }
612
613 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height);
614 if (!myFont.IsNull()
615 && !myFont->ResourceKey().IsEqual (aFontKey))
616 {
617 // font changed
618 const_cast<OpenGl_Text* > (this)->Release (theCtx);
619 }
620
621 if (myFont.IsNull())
622 {
623 myFont = FindFont (theCtx, theTextAspect, myParams.Height, aFontKey);
624 if (myFont.IsNull())
625 {
626 return;
627 }
628 }
629
630 if (myTextures.IsEmpty())
631 {
632 OpenGl_TextFormatter aFormatter;
633 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
634 aFormatter.Reset();
635 aFormatter.Append (theCtx, myString, *myFont.operator->());
636 aFormatter.Format();
637
638 if (OpenGl_GraphicDriver::ToUseVBO() && theCtx->core15 != NULL)
639 {
640 aFormatter.Result (theCtx, myTextures, myVertsVbo, myTCrdsVbo);
641 }
642 else
643 {
644 aFormatter.Result (theCtx, myTextures, myVertsArray, myTCrdsArray);
645 }
646 aFormatter.BndBox (myBndBox);
647 }
648
649 if (myTextures.IsEmpty())
650 {
651 return;
652 }
653
654 myExportHeight = 1.0f;
655 myScaleHeight = 1.0f;
656
657 glMatrixMode (GL_MODELVIEW);
658 glPushMatrix();
659 if (!myIs2d)
660 {
661 // retrieve active matrices for project/unproject calls
662 glGetDoublev (GL_MODELVIEW_MATRIX, myModelMatrix);
663 glGetDoublev (GL_PROJECTION_MATRIX, myProjMatrix);
664 glGetIntegerv (GL_VIEWPORT, myViewport);
665 gluProject (myPoint.x(), myPoint.y(), myPoint.z(),
666 myModelMatrix, myProjMatrix, myViewport,
667 &myWinX, &myWinY, &myWinZ);
668
669 // compute scale factor for constant text height
670 GLdouble x1, y1, z1;
671 gluUnProject (myWinX, myWinY, myWinZ,
672 (GLdouble* )THE_IDENTITY_MATRIX, myProjMatrix, myViewport,
673 &x1, &y1, &z1);
674
675 GLdouble x2, y2, z2;
676 const GLdouble h = (GLdouble )myFont->FTFont()->PointSize();
677 gluUnProject (myWinX, myWinY + h - 1.0, myWinZ,
678 (GLdouble* )THE_IDENTITY_MATRIX, myProjMatrix, myViewport,
679 &x2, &y2, &z2);
680
681 myScaleHeight = (y2 - y1) / h;
682 if (theTextAspect.IsZoomable())
683 {
684 myExportHeight = (float )h;
685 }
686 }
687 myExportHeight = (float )myFont->FTFont()->PointSize() / myExportHeight;
688
689 // push enabled flags to the stack
690 glPushAttrib (GL_ENABLE_BIT);
691
692 // setup depth test
693 if (!myIs2d
694 && theTextAspect.StyleType() != Aspect_TOST_ANNOTATION)
695 {
696 glEnable (GL_DEPTH_TEST);
697 }
698 else
699 {
700 glDisable (GL_DEPTH_TEST);
701 }
702
703 // setup alpha test
704 GLint aTexEnvParam = GL_REPLACE;
705 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
706 if (aTexEnvParam != GL_REPLACE)
707 {
708 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
709 }
710 glAlphaFunc (GL_GEQUAL, 0.285f);
711 glEnable (GL_ALPHA_TEST);
712
713 // setup blending
714 glEnable (GL_BLEND);
715 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
716
717 // activate texture unit
718 glDisable (GL_TEXTURE_1D);
719 glEnable (GL_TEXTURE_2D);
720 if (theCtx->core13 != NULL)
721 {
722 theCtx->core13->glActiveTexture (GL_TEXTURE0);
723 }
724
725 // extra drawings
726 switch (theTextAspect.DisplayType())
727 {
2166f0fa 728 case Aspect_TODT_BLEND:
a174a3c5 729 {
730 glEnable (GL_COLOR_LOGIC_OP);
731 glLogicOp (GL_XOR);
2166f0fa 732 break;
a174a3c5 733 }
2166f0fa
SK
734 case Aspect_TODT_SUBTITLE:
735 {
a174a3c5 736 glColor3fv (theColorSubs.rgb);
737 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
738
739 glBindTexture (GL_TEXTURE_2D, 0);
740 glBegin (GL_QUADS);
741 glVertex2f (myBndBox.Left, myBndBox.Top);
742 glVertex2f (myBndBox.Right, myBndBox.Top);
743 glVertex2f (myBndBox.Right, myBndBox.Bottom);
744 glVertex2f (myBndBox.Left, myBndBox.Bottom);
2166f0fa
SK
745 glEnd();
746 break;
747 }
2166f0fa 748 case Aspect_TODT_DEKALE:
a174a3c5 749 {
750 glColor3fv (theColorSubs.rgb);
751 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
752 drawText (thePrintCtx, theCtx, theTextAspect);
753 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
754 drawText (thePrintCtx, theCtx, theTextAspect);
755 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
756 drawText (thePrintCtx, theCtx, theTextAspect);
757 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
758 drawText (thePrintCtx, theCtx, theTextAspect);
759 break;
760 }
761 case Aspect_TODT_NORMAL:
762 {
2166f0fa
SK
763 break;
764 }
765 }
766
a174a3c5 767 // main draw call
768 glColor3fv (theColorText.rgb);
769 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
770 drawText (thePrintCtx, theCtx, theTextAspect);
2166f0fa 771
a174a3c5 772 // revert OpenGL state
773 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
774 glPopAttrib(); // enable bit
775 glPopMatrix(); // model view matrix was modified
5e27df78 776}