0031193: Visualization - OpenGl_Flipping wrong text position if local transformation set
[occt.git] / src / AIS / AIS_TextLabel.cxx
1 // Created on: 2014-11-10
2 // Copyright (c) 2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <AIS_TextLabel.hxx>
16
17 #include <AIS_InteractiveContext.hxx>
18 #include <Font_FTFont.hxx>
19 #include <Font_FontMgr.hxx>
20 #include <Font_Rect.hxx>
21 #include <Graphic3d_AspectText3d.hxx>
22 #include <Graphic3d_RenderingParams.hxx>
23
24 #include <Prs3d_Text.hxx>
25 #include <Prs3d_TextAspect.hxx>
26
27 #include <Select3D_SensitivePoint.hxx>
28 #include <SelectMgr_Selection.hxx>
29 #include <SelectMgr_EntityOwner.hxx>
30
31 #include <V3d_Viewer.hxx>
32
33 IMPLEMENT_STANDARD_RTTIEXT(AIS_TextLabel,AIS_InteractiveObject)
34
35 //=======================================================================
36 //function : AIS_TextLabel
37 //purpose  :
38 //=======================================================================
39 AIS_TextLabel::AIS_TextLabel()
40 : myText              ("?"),
41   myHasOrientation3D  (Standard_False),
42   myHasOwnAnchorPoint (Standard_True),
43   myHasFlipping       (Standard_False)
44 {
45   myDrawer->SetTextAspect (new Prs3d_TextAspect());
46   myDrawer->SetDisplayMode (0);
47 }
48
49 //=======================================================================
50 //function : SetColor
51 //purpose  :
52 //=======================================================================
53 void AIS_TextLabel::SetColor (const Quantity_Color& theColor)
54 {
55   hasOwnColor = Standard_True;
56   myDrawer->SetColor (theColor);
57   myDrawer->TextAspect()->SetColor (theColor);
58   SynchronizeAspects();
59 }
60
61 //=======================================================================
62 //function : SetTransparency
63 //purpose  :
64 //=======================================================================
65 void AIS_TextLabel::SetTransparency (const Standard_Real theValue)
66 {
67   Quantity_ColorRGBA aTextColor (myDrawer->TextAspect()->Aspect()->Color());
68   aTextColor.SetAlpha (Standard_ShortReal(1.0 - theValue));
69
70   Quantity_ColorRGBA aSubColor (myDrawer->TextAspect()->Aspect()->ColorSubTitle());
71   aSubColor.SetAlpha (aTextColor.Alpha());
72
73   myDrawer->TextAspect()->Aspect()->SetColor (aTextColor);
74   myDrawer->TextAspect()->Aspect()->SetColorSubTitle (aSubColor);
75   myDrawer->SetTransparency (Standard_ShortReal(theValue));
76   SynchronizeAspects();
77 }
78
79 //=======================================================================
80 //function : SetText
81 //purpose  :
82 //=======================================================================
83 void AIS_TextLabel::SetText (const TCollection_ExtendedString& theText)
84 {
85   myText = theText;
86 }
87
88 //=======================================================================
89 //function : SetPosition
90 //purpose  :
91 //=======================================================================
92 void AIS_TextLabel::SetPosition (const gp_Pnt& thePosition)
93 {
94   myOrientation3D.SetLocation (thePosition);
95 }
96
97 //=======================================================================
98 //function : SetHJustification
99 //purpose  :
100 //=======================================================================
101 void AIS_TextLabel::SetHJustification (const Graphic3d_HorizontalTextAlignment theHJust)
102 {
103   myDrawer->TextAspect()->SetHorizontalJustification (theHJust);
104 }
105
106 //=======================================================================
107 //function : SetVJustification
108 //purpose  : Setup vertical justification.
109 //=======================================================================
110 void AIS_TextLabel::SetVJustification (const Graphic3d_VerticalTextAlignment theVJust)
111 {
112   myDrawer->TextAspect()->SetVerticalJustification (theVJust);
113 }
114
115 //=======================================================================
116 //function : SetAngle
117 //purpose  :
118 //=======================================================================
119 void AIS_TextLabel::SetAngle (const Standard_Real theAngle)
120 {
121   myDrawer->TextAspect()->Aspect()->SetTextAngle (theAngle * 180.0 / M_PI);
122 }
123
124 //=======================================================================
125 //function : SetZoom
126 //purpose  :
127 //=======================================================================
128 void AIS_TextLabel::SetZoomable (const Standard_Boolean theIsZoomable)
129 {
130   myDrawer->TextAspect()->Aspect()->SetTextZoomable (theIsZoomable == Standard_True);
131 }
132
133 //=======================================================================
134 //function : SetHeight
135 //purpose  :
136 //=======================================================================
137 void AIS_TextLabel::SetHeight (const Standard_Real theHeight)
138 {
139   myDrawer->TextAspect()->SetHeight (theHeight);
140 }
141
142 //=======================================================================
143 //function : SetAngle
144 //purpose  :
145 //=======================================================================
146 void AIS_TextLabel::SetFontAspect (const Font_FontAspect theFontAspect)
147 {
148   myDrawer->TextAspect()->Aspect()->SetTextFontAspect (theFontAspect);
149 }
150
151 //=======================================================================
152 //function : SetFont
153 //purpose  :
154 //=======================================================================
155 void AIS_TextLabel::SetFont (Standard_CString theFont)
156 {
157   myDrawer->TextAspect()->SetFont (theFont);
158 }
159
160 //=======================================================================
161 //function : SetOrientation3D
162 //purpose  :
163 //=======================================================================
164 void AIS_TextLabel::SetOrientation3D (const gp_Ax2& theOrientation)
165 {
166   myHasOrientation3D = Standard_True;
167   myOrientation3D    = theOrientation;
168 }
169
170 //=======================================================================
171 //function : UnsetOrientation3D
172 //purpose  :
173 //=======================================================================
174 void AIS_TextLabel::UnsetOrientation3D ()
175 {
176   myHasOrientation3D = Standard_False;
177 }
178
179 //=======================================================================
180 //function : Position
181 //purpose  :
182 //=======================================================================
183 const gp_Pnt& AIS_TextLabel::Position() const
184 {
185   return myOrientation3D.Location();
186 }
187
188 //=======================================================================
189 //function : FontName
190 //purpose  :
191 //=======================================================================
192 const TCollection_AsciiString& AIS_TextLabel::FontName() const
193 {
194   return myDrawer->TextAspect()->Aspect()->Font();
195 }
196
197 //=======================================================================
198 //function : FontAspect
199 //purpose  :
200 //=======================================================================
201 Font_FontAspect AIS_TextLabel::FontAspect() const
202 {
203   return myDrawer->TextAspect()->Aspect()->GetTextFontAspect();
204 }
205
206 //=======================================================================
207 //function : Orientation3D
208 //purpose  :
209 //=======================================================================
210 const gp_Ax2& AIS_TextLabel::Orientation3D() const
211 {
212   return myOrientation3D;
213 }
214
215 //=======================================================================
216 //function : HasOrientation3D
217 //purpose  :
218 //=======================================================================
219 Standard_Boolean AIS_TextLabel::HasOrientation3D() const
220 {
221   return myHasOrientation3D;
222 }
223
224 //=======================================================================
225 //function : SetFlipping
226 //purpose  :
227 //=======================================================================
228 void AIS_TextLabel::SetFlipping (const Standard_Boolean theIsFlipping)
229 {
230   myHasFlipping = theIsFlipping;
231 }
232
233 //=======================================================================
234 //function : HasFlipping
235 //purpose  :
236 //=======================================================================
237 Standard_Boolean AIS_TextLabel::HasFlipping() const
238 {
239   return myHasFlipping;
240 }
241
242 //=======================================================================
243 //function : SetDisplayType
244 //purpose  :
245 //=======================================================================
246 void AIS_TextLabel::SetDisplayType (const Aspect_TypeOfDisplayText theDisplayType)
247 {
248   myDrawer->TextAspect()->Aspect()->SetDisplayType(theDisplayType);
249 }
250
251 //=======================================================================
252 //function : SetColorSubTitle
253 //purpose  :
254 //=======================================================================
255 void AIS_TextLabel::SetColorSubTitle (const Quantity_Color& theColor)
256 {
257   myDrawer->TextAspect()->Aspect()->SetColorSubTitle(theColor);
258 }
259
260 //=======================================================================
261 //function : Compute
262 //purpose  :
263 //=======================================================================
264 void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
265                              const Handle(Prs3d_Presentation)&             thePrs,
266                              const Standard_Integer                        theMode)
267 {
268   switch (theMode)
269   {
270     case 0:
271     {
272       Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
273       gp_Pnt aPosition = Position();
274
275       if (myHasOrientation3D)
276       {
277         Standard_Boolean isInit = Standard_False;
278         if (myHasFlipping)
279         {
280           // Get width and height of text
281           Font_FTFontParams aFontParams;
282           aFontParams.PointSize  = (unsigned int )anAsp->Height();
283           aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
284           if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(), anAsp->Aspect()->GetTextFontAspect(), aFontParams))
285           {
286             isInit = Standard_True;
287             const NCollection_String aText (myText.ToExtString());
288             Font_Rect aBndBox = aFont->BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
289             Standard_Real aWidth = Abs (aBndBox.Width());
290             Standard_Real aHeight = Abs (aBndBox.Height());
291             gp_Pnt aCenterOfLabel = aPosition;
292
293             if (anAsp->VerticalJustification() == Graphic3d_VTA_BOTTOM)
294             {
295               aCenterOfLabel.ChangeCoord() += myOrientation3D.YDirection().XYZ() * aHeight * 0.5;
296             }
297             else if (anAsp->VerticalJustification() == Graphic3d_VTA_TOP)
298             {
299               aCenterOfLabel.ChangeCoord() -= myOrientation3D.YDirection().XYZ() * aHeight * 0.5;
300             }
301             if (anAsp->HorizontalJustification() == Graphic3d_HTA_LEFT)
302             {
303               aCenterOfLabel.ChangeCoord() += myOrientation3D.XDirection().XYZ() * aWidth * 0.5;
304             }
305             else if (anAsp->HorizontalJustification() == Graphic3d_HTA_RIGHT)
306             {
307               aCenterOfLabel.ChangeCoord() -= myOrientation3D.XDirection().XYZ() * aWidth * 0.5;
308             }
309
310             if (!anAsp->Aspect()->GetTextZoomable()
311              && (TransformPersistence().IsNull()
312               || TransformPersistence()->Mode() == Graphic3d_TMF_ZoomPers))
313             {
314               anAsp->Aspect()->SetTextZoomable (Standard_True);
315               SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, aPosition));
316               aPosition = gp::Origin();
317             }
318
319             gp_Ax2 aFlippingAxes (aCenterOfLabel, myOrientation3D.Direction(), myOrientation3D.XDirection());
320             Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_True, aFlippingAxes);
321           }
322         }
323
324         gp_Ax2 anOrientation = myOrientation3D;
325         anOrientation.SetLocation (aPosition);
326         Standard_Boolean aHasOwnAnchor = HasOwnAnchorPoint();
327         if (myHasFlipping)
328         {
329           aHasOwnAnchor = Standard_False; // always not using own anchor if flipping
330         }
331         Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, myOrientation3D, aHasOwnAnchor);
332         if (myHasFlipping && isInit)
333         {
334           Prs3d_Root::CurrentGroup (thePrs)->SetFlippingOptions (Standard_False, gp_Ax2());
335         }
336       }
337       else
338       {
339         Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePrs), anAsp, myText, Position());
340       }
341
342       break;
343     }
344   }
345 }
346
347 //=======================================================================
348 //function : ComputeSelection
349 //purpose  :
350 //=======================================================================
351 void AIS_TextLabel::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
352                                       const Standard_Integer             theMode)
353 {
354   switch (theMode)
355   {
356     case 0:
357     {
358       Handle(SelectMgr_EntityOwner)   anEntityOwner   = new SelectMgr_EntityOwner (this, 10);
359       Handle(Select3D_SensitivePoint) aSensitivePoint = new Select3D_SensitivePoint (anEntityOwner, Position());
360       theSelection->Add (aSensitivePoint);
361       break;
362     }
363   }
364 }