0030537: Visualization - wrapping text in font text formatter
[occt.git] / src / AIS / AIS_TextLabel.cxx
CommitLineData
29e2c6d2 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
3f1eb0ab 17#include <AIS_InteractiveContext.hxx>
18#include <Font_FTFont.hxx>
19#include <Font_FontMgr.hxx>
20#include <Font_Rect.hxx>
29e2c6d2 21#include <Graphic3d_AspectText3d.hxx>
3f1eb0ab 22#include <Graphic3d_RenderingParams.hxx>
60f7b225 23#include <Graphic3d_Text.hxx>
29e2c6d2 24
25#include <Prs3d_Text.hxx>
26#include <Prs3d_TextAspect.hxx>
27
3e9c1d1e 28#include <Select3D_SensitiveFace.hxx>
29e2c6d2 29#include <Select3D_SensitivePoint.hxx>
30#include <SelectMgr_Selection.hxx>
31#include <SelectMgr_EntityOwner.hxx>
32
3f1eb0ab 33#include <V3d_Viewer.hxx>
34
92efcf78 35IMPLEMENT_STANDARD_RTTIEXT(AIS_TextLabel,AIS_InteractiveObject)
36
29e2c6d2 37//=======================================================================
38//function : AIS_TextLabel
39//purpose :
40//=======================================================================
41AIS_TextLabel::AIS_TextLabel()
ab9e277f 42: myText ("?"),
43 myHasOrientation3D (Standard_False),
44 myHasOwnAnchorPoint (Standard_True),
45 myHasFlipping (Standard_False)
29e2c6d2 46{
47 myDrawer->SetTextAspect (new Prs3d_TextAspect());
cc99be36 48 myDrawer->SetDisplayMode (0);
29e2c6d2 49}
50
51//=======================================================================
52//function : SetColor
53//purpose :
54//=======================================================================
55void AIS_TextLabel::SetColor (const Quantity_Color& theColor)
56{
57 hasOwnColor = Standard_True;
f838dac4 58 myDrawer->SetColor (theColor);
29e2c6d2 59 myDrawer->TextAspect()->SetColor (theColor);
226fce20 60 SynchronizeAspects();
29e2c6d2 61}
62
63//=======================================================================
85719f0e 64//function : SetTransparency
29e2c6d2 65//purpose :
66//=======================================================================
85719f0e 67void AIS_TextLabel::SetTransparency (const Standard_Real theValue)
29e2c6d2 68{
85719f0e 69 Quantity_ColorRGBA aTextColor (myDrawer->TextAspect()->Aspect()->Color());
70 aTextColor.SetAlpha (Standard_ShortReal(1.0 - theValue));
71
72 Quantity_ColorRGBA aSubColor (myDrawer->TextAspect()->Aspect()->ColorSubTitle());
73 aSubColor.SetAlpha (aTextColor.Alpha());
74
75 myDrawer->TextAspect()->Aspect()->SetColor (aTextColor);
76 myDrawer->TextAspect()->Aspect()->SetColorSubTitle (aSubColor);
77 myDrawer->SetTransparency (Standard_ShortReal(theValue));
226fce20 78 SynchronizeAspects();
29e2c6d2 79}
80
81//=======================================================================
82//function : SetText
83//purpose :
84//=======================================================================
85void AIS_TextLabel::SetText (const TCollection_ExtendedString& theText)
86{
87 myText = theText;
88}
89
90//=======================================================================
91//function : SetPosition
92//purpose :
93//=======================================================================
94void AIS_TextLabel::SetPosition (const gp_Pnt& thePosition)
95{
ce01ec26 96 myOrientation3D.SetLocation (thePosition);
29e2c6d2 97}
98
99//=======================================================================
100//function : SetHJustification
101//purpose :
102//=======================================================================
103void AIS_TextLabel::SetHJustification (const Graphic3d_HorizontalTextAlignment theHJust)
104{
105 myDrawer->TextAspect()->SetHorizontalJustification (theHJust);
106}
107
108//=======================================================================
109//function : SetVJustification
110//purpose : Setup vertical justification.
111//=======================================================================
112void AIS_TextLabel::SetVJustification (const Graphic3d_VerticalTextAlignment theVJust)
113{
114 myDrawer->TextAspect()->SetVerticalJustification (theVJust);
115}
116
117//=======================================================================
118//function : SetAngle
119//purpose :
120//=======================================================================
121void AIS_TextLabel::SetAngle (const Standard_Real theAngle)
122{
123 myDrawer->TextAspect()->Aspect()->SetTextAngle (theAngle * 180.0 / M_PI);
124}
125
126//=======================================================================
127//function : SetZoom
128//purpose :
129//=======================================================================
130void AIS_TextLabel::SetZoomable (const Standard_Boolean theIsZoomable)
131{
b6472664 132 myDrawer->TextAspect()->Aspect()->SetTextZoomable (theIsZoomable == Standard_True);
29e2c6d2 133}
134
135//=======================================================================
136//function : SetHeight
137//purpose :
138//=======================================================================
139void AIS_TextLabel::SetHeight (const Standard_Real theHeight)
140{
141 myDrawer->TextAspect()->SetHeight (theHeight);
142}
143
144//=======================================================================
145//function : SetAngle
146//purpose :
147//=======================================================================
148void AIS_TextLabel::SetFontAspect (const Font_FontAspect theFontAspect)
149{
150 myDrawer->TextAspect()->Aspect()->SetTextFontAspect (theFontAspect);
151}
152
153//=======================================================================
154//function : SetFont
155//purpose :
156//=======================================================================
157void AIS_TextLabel::SetFont (Standard_CString theFont)
158{
64943a51 159 myDrawer->TextAspect()->SetFont (theFont);
29e2c6d2 160}
161
162//=======================================================================
ce01ec26 163//function : SetOrientation3D
164//purpose :
165//=======================================================================
166void AIS_TextLabel::SetOrientation3D (const gp_Ax2& theOrientation)
167{
168 myHasOrientation3D = Standard_True;
169 myOrientation3D = theOrientation;
170}
171
172//=======================================================================
173//function : UnsetOrientation3D
174//purpose :
175//=======================================================================
176void AIS_TextLabel::UnsetOrientation3D ()
177{
178 myHasOrientation3D = Standard_False;
179}
180
181//=======================================================================
182//function : Position
183//purpose :
184//=======================================================================
185const gp_Pnt& AIS_TextLabel::Position() const
186{
187 return myOrientation3D.Location();
188}
189
190//=======================================================================
64943a51 191//function : FontName
192//purpose :
193//=======================================================================
194const TCollection_AsciiString& AIS_TextLabel::FontName() const
195{
196 return myDrawer->TextAspect()->Aspect()->Font();
197}
198
199//=======================================================================
200//function : FontAspect
201//purpose :
202//=======================================================================
203Font_FontAspect AIS_TextLabel::FontAspect() const
204{
205 return myDrawer->TextAspect()->Aspect()->GetTextFontAspect();
206}
207
208//=======================================================================
ce01ec26 209//function : Orientation3D
210//purpose :
211//=======================================================================
212const gp_Ax2& AIS_TextLabel::Orientation3D() const
213{
214 return myOrientation3D;
215}
216
217//=======================================================================
3f1eb0ab 218//function : HasOrientation3D
ce01ec26 219//purpose :
220//=======================================================================
221Standard_Boolean AIS_TextLabel::HasOrientation3D() const
222{
223 return myHasOrientation3D;
224}
225
226//=======================================================================
3f1eb0ab 227//function : SetFlipping
228//purpose :
229//=======================================================================
230void AIS_TextLabel::SetFlipping (const Standard_Boolean theIsFlipping)
231{
232 myHasFlipping = theIsFlipping;
233}
234
235//=======================================================================
236//function : HasFlipping
237//purpose :
238//=======================================================================
239Standard_Boolean AIS_TextLabel::HasFlipping() const
240{
241 return myHasFlipping;
242}
243
244//=======================================================================
61b0191c 245//function : SetDisplayType
246//purpose :
247//=======================================================================
248void AIS_TextLabel::SetDisplayType (const Aspect_TypeOfDisplayText theDisplayType)
249{
250 myDrawer->TextAspect()->Aspect()->SetDisplayType(theDisplayType);
251}
252
253//=======================================================================
254//function : SetColorSubTitle
255//purpose :
256//=======================================================================
257void AIS_TextLabel::SetColorSubTitle (const Quantity_Color& theColor)
258{
259 myDrawer->TextAspect()->Aspect()->SetColorSubTitle(theColor);
260}
261
262//=======================================================================
29e2c6d2 263//function : Compute
264//purpose :
265//=======================================================================
266void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
267 const Handle(Prs3d_Presentation)& thePrs,
268 const Standard_Integer theMode)
269{
270 switch (theMode)
271 {
272 case 0:
273 {
274 Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
3f1eb0ab 275 gp_Pnt aPosition = Position();
ce01ec26 276
3e9c1d1e 277 const Standard_Boolean isTextZoomable = anAsp->Aspect()->GetTextZoomable();
278 if (myHasOrientation3D)
279 {
280 anAsp->Aspect()->SetTextZoomable (myHasFlipping ? Standard_True : Standard_False);
281 SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, aPosition));
282 aPosition = gp::Origin();
283 }
284 else if (isTextZoomable
285 || TransformPersistence().IsNull()
286 || TransformPersistence()->Mode() != Graphic3d_TMF_2d)
287 {
288 Handle(Graphic3d_TransformPers) aTrsfPers =
289 new Graphic3d_TransformPers (isTextZoomable ? Graphic3d_TMF_RotatePers : Graphic3d_TMF_ZoomRotatePers, aPosition);
290 SetTransformPersistence (aTrsfPers);
291 aPosition = gp::Origin();
292 }
293
294 gp_Pnt aCenterOfLabel;
295 Standard_Real aWidth, aHeight;
296
297 Standard_Boolean isInit = calculateLabelParams (aPosition, aCenterOfLabel, aWidth, aHeight);
ce01ec26 298 if (myHasOrientation3D)
299 {
3f1eb0ab 300 if (myHasFlipping)
301 {
3e9c1d1e 302 gp_Ax2 aFlippingAxes (aCenterOfLabel, myOrientation3D.Direction(), myOrientation3D.XDirection());
d6c48921 303 thePrs->CurrentGroup()->SetFlippingOptions (Standard_True, aFlippingAxes);
3f1eb0ab 304 }
3f1eb0ab 305 gp_Ax2 anOrientation = myOrientation3D;
306 anOrientation.SetLocation (aPosition);
ab9e277f 307 Standard_Boolean aHasOwnAnchor = HasOwnAnchorPoint();
308 if (myHasFlipping)
309 {
310 aHasOwnAnchor = Standard_False; // always not using own anchor if flipping
311 }
60f7b225 312 Handle(Graphic3d_Text) aText =
313 Prs3d_Text::Draw (thePrs->CurrentGroup(), anAsp, myText, anOrientation, aHasOwnAnchor);
314 aText->SetTextFormatter (myFormatter);
3f1eb0ab 315 if (myHasFlipping && isInit)
316 {
d6c48921 317 thePrs->CurrentGroup()->SetFlippingOptions (Standard_False, gp_Ax2());
3f1eb0ab 318 }
ce01ec26 319 }
320 else
321 {
60f7b225 322 Handle(Graphic3d_Text) aText =
323 Prs3d_Text::Draw (thePrs->CurrentGroup(), anAsp, myText, aPosition);
324 aText->SetTextFormatter (myFormatter);
3e9c1d1e 325 }
326
327 if (isInit)
328 {
329 const Standard_Real aDx = aWidth * 0.5;
330 const Standard_Real aDy = aHeight * 0.5;
331 gp_Trsf aLabelPlane = calculateLabelTrsf (aPosition, aCenterOfLabel);
332
333 gp_Pnt aMinPnt = gp_Pnt (-aDx, -aDy, 0.0).Transformed (aLabelPlane);
334 gp_Pnt aMaxPnt = gp_Pnt ( aDx, aDy, 0.0).Transformed (aLabelPlane);
335
d6c48921 336 Graphic3d_BndBox4f& aBox = thePrs->CurrentGroup()->ChangeBoundingBox();
3e9c1d1e 337 aBox.Add (Graphic3d_Vec4 ((float) aMinPnt.X(), (float) aMinPnt.Y(), (float) aMinPnt.Z(), 1.0));
338 aBox.Add (Graphic3d_Vec4 ((float) aMaxPnt.X(), (float) aMaxPnt.Y(), (float) aMaxPnt.Z(), 1.0));
ce01ec26 339 }
340
29e2c6d2 341 break;
342 }
343 }
344}
345
346//=======================================================================
347//function : ComputeSelection
348//purpose :
349//=======================================================================
350void AIS_TextLabel::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
351 const Standard_Integer theMode)
352{
353 switch (theMode)
354 {
355 case 0:
356 {
3e9c1d1e 357 Handle(SelectMgr_EntityOwner) anEntityOwner = new SelectMgr_EntityOwner (this, 10);
358
359 gp_Pnt aPosition = Position();
360 if (!TransformPersistence().IsNull() && TransformPersistence()->Mode() != Graphic3d_TMF_2d)
361 {
362 aPosition = gp::Origin();
363 }
364
365 gp_Pnt aCenterOfLabel;
366 Standard_Real aWidth, aHeight;
367
368 if (!calculateLabelParams (aPosition, aCenterOfLabel, aWidth, aHeight))
369 {
370 Handle(Select3D_SensitivePoint) aTextSensitive = new Select3D_SensitivePoint (anEntityOwner, aPosition);
371 theSelection->Add (aTextSensitive);
372 break;
373 }
374
375 const Standard_Real aDx = aWidth * 0.5;
376 const Standard_Real aDy = aHeight * 0.5;
377 gp_Trsf aLabelPlane = calculateLabelTrsf (aPosition, aCenterOfLabel);
378
379 // sensitive planar rectangle for text
380 TColgp_Array1OfPnt aRectanglePoints (1, 5);
381 aRectanglePoints.ChangeValue (1) = gp_Pnt (-aDx, -aDy, 0.0).Transformed (aLabelPlane);
382 aRectanglePoints.ChangeValue (2) = gp_Pnt (-aDx, aDy, 0.0).Transformed (aLabelPlane);
383 aRectanglePoints.ChangeValue (3) = gp_Pnt ( aDx, aDy, 0.0).Transformed (aLabelPlane);
384 aRectanglePoints.ChangeValue (4) = gp_Pnt ( aDx, -aDy, 0.0).Transformed (aLabelPlane);
385 aRectanglePoints.ChangeValue (5) = aRectanglePoints.Value (1);
386
387 Handle(Select3D_SensitiveFace) aTextSensitive =
388 new Select3D_SensitiveFace (anEntityOwner, aRectanglePoints, Select3D_TOS_INTERIOR);
389 theSelection->Add (aTextSensitive);
390
29e2c6d2 391 break;
392 }
393 }
394}
3e9c1d1e 395
396//=======================================================================
397//function : calculateLabelParams
398//purpose :
399//=======================================================================
400Standard_Boolean AIS_TextLabel::calculateLabelParams (const gp_Pnt& thePosition,
401 gp_Pnt& theCenterOfLabel,
402 Standard_Real& theWidth,
403 Standard_Real& theHeight) const
404{
405 // Get width and height of text
406 Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
407 Font_FTFontParams aFontParams;
408 aFontParams.PointSize = (unsigned int) anAsp->Height();
409 aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
410
411 Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(),
412 anAsp->Aspect()->GetTextFontAspect(),
413 aFontParams);
414 if (aFont.IsNull())
415 {
416 return Standard_False;
417 }
418
419 const NCollection_String aText (myText.ToExtString());
420 Font_Rect aBndBox = aFont->BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
421 theWidth = Abs (aBndBox.Width());
422 theHeight = Abs (aBndBox.Height());
423
424 theCenterOfLabel = thePosition;
425 if (anAsp->VerticalJustification() == Graphic3d_VTA_BOTTOM)
426 {
427 theCenterOfLabel.ChangeCoord() += myOrientation3D.YDirection().XYZ() * theHeight * 0.5;
428 }
429 else if (anAsp->VerticalJustification() == Graphic3d_VTA_TOP)
430 {
431 theCenterOfLabel.ChangeCoord() -= myOrientation3D.YDirection().XYZ() * theHeight * 0.5;
432 }
433 if (anAsp->HorizontalJustification() == Graphic3d_HTA_LEFT)
434 {
435 theCenterOfLabel.ChangeCoord() += myOrientation3D.XDirection().XYZ() * theWidth * 0.5;
436 }
437 else if (anAsp->HorizontalJustification() == Graphic3d_HTA_RIGHT)
438 {
439 theCenterOfLabel.ChangeCoord() -= myOrientation3D.XDirection().XYZ() * theWidth * 0.5;
440 }
441
442 return Standard_True;
443}
444
445//=======================================================================
446//function : calculateLabelTrsf
447//purpose :
448//=======================================================================
449gp_Trsf AIS_TextLabel::calculateLabelTrsf (const gp_Pnt& thePosition, gp_Pnt& theCenterOfLabel) const
450{
451 const Standard_Real anAngle = myDrawer->TextAspect()->Aspect()->TextAngle() * M_PI / 180.0;
452 const gp_Ax1 aRotAxis (thePosition, gp_Dir (0.0, 0.0, 1.0));
453
454 gp_Ax2 anOrientation = myOrientation3D;
455 anOrientation.Rotate (aRotAxis, anAngle);
456 theCenterOfLabel.Rotate (aRotAxis, anAngle);
457
458 gp_Trsf aLabelPlane;
459 aLabelPlane.SetTransformation (anOrientation, gp::XOY());
460 aLabelPlane.SetTranslationPart (theCenterOfLabel.XYZ());
461
462 return aLabelPlane;
463}