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