fec36cbc1730e716d5380e20da1b77c68eb8fd1f
[occt.git] / src / OpenGl / OpenGl_Text.cxx
1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
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
20
21 #include <OpenGl_GlCore11.hxx>
22 #include <OpenGl_Text.hxx>
23 #include <OpenGl_Memory.hxx>
24 #include <OpenGl_AspectText.hxx>
25 #include <OpenGl_Structure.hxx>
26
27 #include <GL/glu.h> // gluUnProject()
28
29 /*----------------------------------------------------------------------*/
30
31 OpenGl_Text::OpenGl_Text (const TCollection_ExtendedString& AText,
32                         const Graphic3d_Vertex& APoint,
33                         const Standard_Real AHeight,
34                         const Graphic3d_HorizontalTextAlignment AHta,
35                         const Graphic3d_VerticalTextAlignment AVta)
36 : myString(NULL)
37 {
38   const Techar *str = (const Techar *) AText.ToExtString();
39
40   //szv: instead of strlen + 1
41   int i = 0; while (str[i++]);
42
43   wchar_t *wstr = new wchar_t[i];
44
45   //szv: instead of memcpy
46   i = 0; while (wstr[i++] = (wchar_t)(*str++));
47   if (myString) delete[] myString;
48   myString = wstr;
49
50   Standard_Real X, Y, Z;
51   APoint.Coord(X, Y, Z);
52   myAttachPnt.xyz[0] = float (X);
53   myAttachPnt.xyz[1] = float (Y);
54   myAttachPnt.xyz[2] = float (Z);
55
56   myParam.Height = int (AHeight);
57
58   myParam.HAlign = AHta;
59   myParam.VAlign = AVta;
60 }
61
62 /*----------------------------------------------------------------------*/
63
64 OpenGl_Text::~OpenGl_Text ()
65 {
66   if (myString)
67     delete[] myString;
68 }
69
70 /*----------------------------------------------------------------------*/
71
72 void OpenGl_Text::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
73 {
74   if ( AWorkspace->DegenerateModel > 0 && AWorkspace->SkipRatio >= 1.f )
75     return;
76
77   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText( Standard_True );
78
79   const TEL_COLOUR *tcolor, *scolor;
80
81   // Use highlight colours
82   if( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
83   {                         
84     tcolor = scolor = AWorkspace->HighlightColor;
85   }
86   else
87   {
88     tcolor = &aspect_text->Color();
89     scolor = &aspect_text->SubtitleColor();
90   }
91
92   // Handle annotation style
93   GLboolean flag_zbuffer = GL_FALSE;
94   if (aspect_text->StyleType() == Aspect_TOST_ANNOTATION)
95   {
96     flag_zbuffer = glIsEnabled(GL_DEPTH_TEST);
97     if (flag_zbuffer) glDisable(GL_DEPTH_TEST);
98   }
99
100   AWorkspace->SetTextParam(&myParam);
101
102   GLdouble        modelMatrix[16], projMatrix[16];
103   GLint           viewport[4];
104   GLdouble        objrefX, objrefY, objrefZ;
105   GLdouble        objX, objY, objZ;
106   GLdouble        obj1X, obj1Y, obj1Z;
107   GLdouble        obj2X, obj2Y, obj2Z;
108   GLdouble        obj3X, obj3Y, obj3Z;
109   GLdouble        winx1, winy1, winz1;
110   GLdouble        winx, winy, winz;
111   GLint           status;
112
113   /* display type of text */
114   if (aspect_text->DisplayType() != Aspect_TODT_NORMAL)
115   {
116     /* Optimisation: il faudrait ne faire le Get qu'une fois par Redraw */
117     glGetIntegerv (GL_VIEWPORT, viewport);
118     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
119     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
120
121     switch (aspect_text->DisplayType())
122     {
123     case Aspect_TODT_BLEND:
124       glEnable(GL_COLOR_LOGIC_OP);
125       glLogicOp(GL_XOR);
126       break;
127     case Aspect_TODT_SUBTITLE:
128     {
129       int sWidth, sAscent, sDescent;
130       AWorkspace->StringSize(myString, sWidth, sAscent, sDescent);
131
132       objrefX = (float)myAttachPnt.xyz[0];   
133       objrefY = (float)myAttachPnt.xyz[1];   
134       objrefZ = (float)myAttachPnt.xyz[2];
135       status = gluProject (objrefX, objrefY, objrefZ, modelMatrix, projMatrix, viewport,
136         &winx1, &winy1, &winz1);
137
138       winx = winx1;
139       winy = winy1-sDescent;
140       winz = winz1+0.00001;     
141       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
142         &objX, &objY, &objZ);
143
144       winx = winx1 + sWidth;
145       winy = winy1-sDescent;
146       winz = winz1+0.00001; /* il vaut mieux F+B / 1000000 ? */     
147       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
148         &obj1X, &obj1Y, &obj1Z);
149
150       winx = winx1 + sWidth;
151       winy = winy1 + sAscent;
152       winz = winz1+0.00001;     
153       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
154         &obj2X, &obj2Y, &obj2Z);
155
156       winx = winx1;
157       winy = winy1+ sAscent;
158       winz = winz1+0.00001;   
159       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
160         &obj3X, &obj3Y, &obj3Z);
161
162       glColor3fv( scolor->rgb );
163       glBegin(GL_POLYGON);
164       glVertex3d(objX, objY, objZ);
165       glVertex3d(obj1X, obj1Y, obj1Z);
166       glVertex3d(obj2X, obj2Y, obj2Z);
167       glVertex3d(obj3X, obj3Y, obj3Z);
168       glEnd();
169       break;
170     }
171
172     case Aspect_TODT_DEKALE:
173       objrefX = (float)myAttachPnt.xyz[0];   
174       objrefY = (float)myAttachPnt.xyz[1];   
175       objrefZ = (float)myAttachPnt.xyz[2];
176       status = gluProject (objrefX, objrefY, objrefZ, modelMatrix, projMatrix, viewport,
177         &winx1, &winy1, &winz1);
178
179       winx = winx1+1;
180       winy = winy1+1;
181       winz = winz1+0.00001;     
182       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
183         &objX, &objY, &objZ);
184
185       glColor3fv( scolor->rgb );
186       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
187       winx = winx1-1;
188       winy = winy1-1;
189       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
190         &objX, &objY, &objZ);
191
192       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
193       winx = winx1-1;
194       winy = winy1+1;
195       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
196         &objX, &objY, &objZ); 
197
198       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
199       winx = winx1+1;
200       winy = winy1-1;
201       status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
202         &objX, &objY, &objZ);
203       AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
204       break;
205     }
206   }
207
208   glColor3fv( tcolor->rgb );
209   AWorkspace->RenderText( myString, 0, (float)myAttachPnt.xyz[0], (float)myAttachPnt.xyz[1],(float)myAttachPnt.xyz[2] );
210   /* maj attributs */
211   if (flag_zbuffer) glEnable(GL_DEPTH_TEST);
212   if (aspect_text->DisplayType() == Aspect_TODT_BLEND)
213   {
214     glDisable(GL_COLOR_LOGIC_OP);
215   }
216 }
217
218 /*----------------------------------------------------------------------*/