Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Graphic2d / Graphic2d_FramedText.cxx
1 // S3824        10/06/98 : GG ;
2 //              1) La methode "Fit" comporte un argum optionnel supplementaire
3 //                 "Expand" permettant de ne pas ajuster la largeur du texte
4 //                  lorsque celle ci est < a la taille du FIT.
5 //              2) La methode "Trunc" permet de tronquer le texte a la
6 //                 taille precisee.
7
8 #define PRO14304        //GG_160698
9 //              Corrige une erreur de calcul sur les MINMAX provoquant
10 //              la disparition du text
11
12 #define PERF    //GG_200898
13 //              The MinMax are now computed at the right time and no more
14 //              soon an attribute has change 
15 //              (see the redefined method ComputeMinMax()).
16
17 #define BUC60583        //GG_300999 Enable to compute correctly a
18 //                      Mirror transformation
19
20 #include <Graphic2d_FramedText.ixx>
21 #include <Aspect_WindowDriver.hxx>
22
23 #include <Graphic2d_Primitive.pxx>
24
25 Graphic2d_FramedText::Graphic2d_FramedText
26    (const Handle(Graphic2d_GraphicObject)& aGraphicObject,
27     const TCollection_ExtendedString& aText,
28     const Standard_Real X, const Standard_Real Y,
29     const Quantity_PlaneAngle anAngle,
30     const Quantity_Ratio aMargin,
31     const Aspect_TypeOfText aType,
32     const Quantity_Factor aScale)
33     : Graphic2d_Text (aGraphicObject,aText,X,Y,anAngle,aType,aScale),
34         myMargin(Standard_ShortReal( aMargin )) {
35
36     SetFrameColorIndex();
37     SetFrameWidthIndex();
38
39 #ifndef PERF
40     ComputeMinMax();
41 #endif
42 }
43
44 void Graphic2d_FramedText::SetFrameColorIndex (const Standard_Integer anIndex) {
45
46         myFrameColorIndex = anIndex;
47 }
48
49 void Graphic2d_FramedText::SetFrameWidthIndex (const Standard_Integer anIndex) { 
50         myFrameWidthIndex = anIndex;
51  
52 }
53
54 void Graphic2d_FramedText::Draw (const Handle(Graphic2d_Drawer)& aDrawer) {
55 Standard_Boolean IsIn = Standard_False;
56 Standard_ShortReal hscale = (myIsZoomable) ? 
57            Standard_ShortReal( myHScale * aDrawer->Scale() )
58          : Standard_ShortReal( myHScale );
59 Standard_ShortReal wscale = (myIsZoomable) ? 
60            Standard_ShortReal( myWScale * aDrawer->Scale() )
61          : Standard_ShortReal( myWScale );
62 Standard_ShortReal ox = aDrawer->ConvertMapToFrom(myDeltax);
63 Standard_ShortReal oy = aDrawer->ConvertMapToFrom(myDeltay);
64
65 #ifdef PERF
66         if( (myMaxX < myMinX) || (myMaxY < myMinY) ) {
67           if( !ComputeMinMax() ) return;
68         }
69 #else
70         if( myResetFlag ) {
71           ComputeMinMax();
72         }   
73 #endif
74
75         if (! myGOPtr->IsTransformed ()) {
76           IsIn = aDrawer->IsIn (myMinX+ox,myMaxX+ox,myMinY+oy,myMaxY+oy);
77           if (IsIn) {
78             aDrawer->SetFramedTextAttrib(myColorIndex,myFrameColorIndex,
79                                         myFrameWidthIndex,myFontIndex,
80                                         mySlant,hscale,wscale,myIsUnderlined);
81             Standard_ShortReal dx = myDx,dy = myDy;
82             if( myAngle != 0. ) {
83               Standard_ShortReal cosa = Standard_ShortReal( Cos(myAngle) );
84               Standard_ShortReal sina = Standard_ShortReal( Sin(myAngle) );
85
86               dx = XROTATE(myDx,myDy) ;
87               dy = YROTATE(myDx,myDy) ;
88             }
89             aDrawer->MapFramedTextFromTo(myText,myX+dx,myY+dy,myAngle,myMargin,
90                                                 myDeltax,myDeltay,myType);
91           }
92         } else {
93           Standard_ShortReal minx,miny,maxx,maxy;
94           gp_GTrsf2d aTrsf = myGOPtr->Transform ();
95           MinMax(minx,maxx,miny,maxy);
96           IsIn = aDrawer->IsIn (minx+ox,maxx+ox,miny+oy,maxy+oy);
97           if (IsIn) {
98             Standard_Real A = Standard_Real (myX);
99             Standard_Real B = Standard_Real (myY);
100             Standard_Real C = Standard_Real (myAngle);
101             Standard_Real cosa = Cos (C);
102             Standard_Real sina = Sin (C);
103             aTrsf.Transforms (A, B);
104
105             Standard_ShortReal a = Standard_ShortReal (A);
106             Standard_ShortReal b = Standard_ShortReal (B);
107 #ifdef BUC60583
108             aTrsf.Transforms (cosa, sina);
109             A = B = 0.;
110             aTrsf.Transforms (A, B);
111             cosa -= A; sina -= B;
112             if( aTrsf.IsNegative() ) hscale = - hscale;
113 #else
114             // Pour calculer les nouveaux angles d'ouverture
115             // le calcul est fait sur le cercle trigonometrique
116             // et l'on tient pas compte dans ce cas de la translation.
117             aTrsf.SetValue (1, 3, 0.0);
118             aTrsf.SetValue (2, 3, 0.0);
119             aTrsf.Transforms (cosa, sina);
120 #endif
121             Standard_ShortReal angle = Standard_ShortReal (atan2(sina,cosa));
122             if( myIsZoomable ) {
123               hscale *= Standard_ShortReal(Sqrt(cosa*cosa + sina*sina));
124               wscale *= Standard_ShortReal (Sqrt(cosa*cosa + sina*sina));
125             }
126
127             aDrawer->SetFramedTextAttrib(myColorIndex,myFrameColorIndex,
128                                         myFrameWidthIndex,myFontIndex,
129                                         mySlant,hscale,wscale,myIsUnderlined);
130             Standard_ShortReal dx = myDx,dy = myDy;
131             if( angle != 0. ) {
132               dx = Standard_ShortReal( XROTATE(myDx,myDy) );
133               dy = Standard_ShortReal( YROTATE(myDx,myDy) );
134             }
135             a += dx; b += dy;
136             aDrawer->MapFramedTextFromTo(myText,a,b,angle,myMargin,
137                                                 myDeltax,myDeltay,myType);
138           }
139         }
140 }
141
142
143 Standard_Boolean Graphic2d_FramedText::Pick (const Standard_ShortReal X,
144                                        const Standard_ShortReal Y,
145                                        const Standard_ShortReal aPrecision,
146                                        const Handle(Graphic2d_Drawer)& aDrawer) 
147 {
148 Standard_Boolean theStatus = Standard_False;
149 Standard_ShortReal width,height,xoffset,yoffset,mwidth,mheight;
150 Standard_ShortReal hscale = (myIsZoomable) ? 
151          Standard_ShortReal( myHScale * aDrawer->Scale() )
152        : Standard_ShortReal( myHScale );
153 Standard_ShortReal wscale = (myIsZoomable) ? 
154          Standard_ShortReal( myWScale * aDrawer->Scale() )
155        : Standard_ShortReal( myWScale );
156
157 Standard_ShortReal TX = X, TY = Y;
158 Standard_ShortReal ox = aDrawer->ConvertMapToFrom(myDeltax);
159 Standard_ShortReal oy = aDrawer->ConvertMapToFrom(myDeltay);
160
161   if (IsInMinMax (X-ox, Y-oy, aPrecision)) {
162     if (myGOPtr->IsTransformed ()) {
163         gp_GTrsf2d aTrsf = (myGOPtr->Transform ()).Inverted ();
164         Standard_Real RX = Standard_Real (X), RY = Standard_Real (Y);
165         aTrsf.Transforms (RX, RY); 
166         TX = Standard_ShortReal (RX); TY = Standard_ShortReal (RY);
167     }
168     aDrawer->SetTextAttrib(myColorIndex,myFontIndex,
169                                         mySlant,hscale,wscale,myIsUnderlined);
170     if( !aDrawer->GetTextSize(myText,width,height,xoffset,yoffset) ) {
171       mwidth = mheight = width = height = xoffset = yoffset = 0.;
172     } else {
173       mwidth = mheight = height*myMargin;   
174     }
175     Standard_ShortReal cosa = Standard_ShortReal( Cos(-myAngle) );
176     Standard_ShortReal sina = Standard_ShortReal( Sin(-myAngle) );
177     Standard_ShortReal dx = TX-(myX+ox+myDx);
178     Standard_ShortReal dy = TY-(myY+oy+myDy);
179     Standard_ShortReal x = XROTATE(dx,dy);
180     Standard_ShortReal y = YROTATE(dx,dy);
181  
182     theStatus =  (x >=  -mwidth + xoffset - aPrecision)
183             &&   (x <= width + mwidth  + xoffset + aPrecision)
184             &&   (y >= - mheight - yoffset - aPrecision)
185             &&   (y <= height + mheight - yoffset + aPrecision);
186   }
187    
188   return theStatus;
189 }
190
191 Standard_Boolean Graphic2d_FramedText::TextSize ( Quantity_Length &aWidth, 
192                                             Quantity_Length &aHeight,
193                                             Quantity_Length &anXoffset,
194                                             Quantity_Length &anYoffset) const {
195 Handle(Graphic2d_Drawer) aDrawer = Drawer();
196  
197     if( !aDrawer.IsNull() && aDrawer->IsWindowDriver() ) {
198         Standard_ShortReal hscale = (myIsZoomable) ? 
199             Standard_ShortReal( myHScale * aDrawer->Scale() )
200           : Standard_ShortReal( myHScale );
201         Standard_ShortReal wscale = (myIsZoomable) ? 
202             Standard_ShortReal( myWScale * aDrawer->Scale() )
203           : Standard_ShortReal( myWScale );
204         Standard_ShortReal width,height,xoffset,yoffset;
205         aDrawer->SetTextAttrib(myColorIndex,myFontIndex,
206                                         mySlant,hscale,wscale,myIsUnderlined);
207                                          
208         aDrawer->GetTextSize(myText,width,height,xoffset,yoffset);
209         aWidth = width + 2.*height*myMargin;
210         aHeight = height + 2.*height*myMargin;
211         anXoffset = xoffset - height*myMargin;
212         anYoffset = yoffset + height*myMargin;
213         return Standard_True;
214     } else {
215         aWidth = aHeight = anXoffset = anYoffset = 0.;
216         return Standard_False;
217     }
218  
219 }
220
221 Standard_Integer Graphic2d_FramedText::FrameColorIndex() const {
222
223         return myFrameColorIndex;
224 }
225
226 Standard_Integer Graphic2d_FramedText::FrameWidthIndex() const {
227
228         return myFrameWidthIndex;
229 }
230
231 Quantity_Ratio Graphic2d_FramedText::Margin() const {
232
233         return Quantity_Ratio(myMargin);
234 }
235
236 Standard_Boolean Graphic2d_FramedText::Fit(const Quantity_Length aWidth,const Quantity_Length aHeight,const Standard_Boolean Adjust,const Standard_Boolean Expand) {
237 Quantity_Length twidth,theight,xoffset,yoffset;
238 Standard_ShortReal wscale,hscale;
239 Standard_Boolean status;
240
241     myAdjustFlag = Adjust;
242     if(( status = TextSize(twidth,theight,xoffset,yoffset) )) {
243       wscale = Standard_ShortReal( aWidth/twidth );
244       if( wscale > 0. ) {
245         if( Expand || (twidth > aWidth) ) myWScale *= wscale;
246       }
247       hscale = Standard_ShortReal( aHeight/theight );
248       if( hscale > 0. ) myHScale *= hscale;
249 #ifdef PERF
250       myMinX = myMinY = ShortRealLast ();
251       myMaxX = myMaxY = ShortRealFirst ();
252 #else
253       myResetFlag = Standard_True;
254       ComputeMinMax();
255 #endif
256     }
257
258     return status;
259 }
260
261 Standard_Boolean Graphic2d_FramedText::Trunc(const Quantity_Length aWidth) {
262 Quantity_Length twidth,theight,txoffset,tyoffset;
263 //Standard_ShortReal wscale,hscale;
264 Standard_Boolean status;
265
266     if(( status = TextSize(twidth,theight,txoffset,tyoffset) )) {
267       Standard_Integer l = myText.Length();
268       while( (l > 1) && (twidth > aWidth) ) {
269         --l;
270         myText.Split(l);
271         TextSize(twidth,theight,txoffset,tyoffset);
272       }
273 #ifdef PERF
274       myMinX = myMinY = ShortRealLast ();
275       myMaxX = myMaxY = ShortRealFirst ();
276 #else
277       myResetFlag = Standard_True;
278       this->ComputeMinMax();
279 #endif
280     }
281
282     return status;
283 }
284
285 Standard_Boolean Graphic2d_FramedText::ComputeMinMax() {
286 Handle(Graphic2d_Drawer) aDrawer = Drawer();
287 Standard_Boolean status = Standard_False;
288
289     if( !aDrawer.IsNull() && aDrawer->IsWindowDriver() ) {
290           Standard_ShortReal hscale = 
291                 (myIsZoomable) ? 
292         Standard_ShortReal( myHScale * aDrawer->Scale() )
293       : Standard_ShortReal( myHScale );
294           Standard_ShortReal wscale = 
295                 (myIsZoomable) ? 
296         Standard_ShortReal( myWScale * aDrawer->Scale() )
297       : Standard_ShortReal( myWScale );
298       Standard_ShortReal width,height,xoffset,yoffset;
299           aDrawer->SetTextAttrib(myColorIndex,myFontIndex,
300                                         mySlant,hscale,wscale,myIsUnderlined);
301           if(( status = aDrawer->GetTextSize(myText,width,height,xoffset,yoffset) )) {
302             Standard_ShortReal dxm,dym;
303 #ifndef PERF
304             myResetFlag = Standard_False; 
305 #endif
306             dxm = dym = height*myMargin ;
307
308             switch( myAlignment ) {
309               case Graphic2d_TOA_LEFT:
310                 myDx = myDy = 0.;
311                 break;
312               case Graphic2d_TOA_RIGHT:
313                 myDx = -width; myDy = 0.;
314                 break;
315               case Graphic2d_TOA_CENTER:
316                 myDx = Standard_ShortReal( -width/2. ); myDy = 0.;
317                 break;
318               case Graphic2d_TOA_TOPLEFT:
319                 myDx = 0.; myDy = yoffset-height;
320                 break;
321               case Graphic2d_TOA_TOPRIGHT:
322                 myDx = -width; myDy = yoffset-height;
323                 break;
324               case Graphic2d_TOA_TOPCENTER:
325                 myDx = Standard_ShortReal( -width/2.); myDy = yoffset-height;
326                 break;
327               case Graphic2d_TOA_MEDIUMLEFT:
328                 myDx = 0.; myDy = Standard_ShortReal( (yoffset-height)/2. );
329                 break;
330               case Graphic2d_TOA_MEDIUMRIGHT:
331                 myDx = -width; myDy = Standard_ShortReal( (yoffset-height)/2. );
332                 break;
333               case Graphic2d_TOA_MEDIUMCENTER:
334                 myDx = Standard_ShortReal( -width/2.); 
335                 myDy = Standard_ShortReal( (yoffset-height)/2. );
336                 break;
337               case Graphic2d_TOA_BOTTOMLEFT:
338                 myDx = 0.; myDy = yoffset;
339                 break;
340               case Graphic2d_TOA_BOTTOMRIGHT:
341                 myDx = -width; myDy = yoffset;
342                 break;
343               case Graphic2d_TOA_BOTTOMCENTER:
344                 myDx = Standard_ShortReal( -width/2. ); myDy = yoffset;
345                 break;
346             }
347             if( myAdjustFlag ) {
348               myDx += dxm - xoffset; myDy += dym + yoffset;
349             }
350             Standard_ShortReal xmin = myDx - dxm + xoffset;
351             Standard_ShortReal ymin = myDy - dym - yoffset;
352             Standard_ShortReal xmax = xmin + width + 2*dxm;
353             Standard_ShortReal ymax = ymin + height + 2*dym;
354
355             myMinX = myMinY = ShortRealLast();
356             myMaxX = myMaxY = ShortRealFirst();
357             if( myAngle != 0. ) {
358               Standard_ShortReal cosa = Standard_ShortReal( Cos(myAngle) );
359               Standard_ShortReal sina = Standard_ShortReal( Sin(myAngle) );
360               Standard_ShortReal dx,dy;
361  
362               dx = XROTATE(xmin,ymin) ;
363               dy = YROTATE(xmin,ymin) ;
364               myMinX = Min(myMinX,myX+dx) ;
365               myMinY = Min(myMinY,myY+dy) ;
366               myMaxX = Max(myMaxX,myX+dx) ;
367               myMaxY = Max(myMaxY,myY+dy) ;
368
369               dx = XROTATE(xmin,ymax) ;
370               dy = YROTATE(xmin,ymax) ;
371               myMinX = Min(myMinX,myX+dx) ;
372               myMinY = Min(myMinY,myY+dy) ;
373               myMaxX = Max(myMaxX,myX+dx) ;
374               myMaxY = Max(myMaxY,myY+dy) ;
375
376               dx = XROTATE(xmax,ymax) ;
377               dy = YROTATE(xmax,ymax) ;
378               myMinX = Min(myMinX,myX+dx) ;
379               myMinY = Min(myMinY,myY+dy) ;
380               myMaxX = Max(myMaxX,myX+dx) ;
381               myMaxY = Max(myMaxY,myY+dy) ;
382  
383               dx = XROTATE(xmax,ymin) ;
384               dy = YROTATE(xmax,ymin) ;
385               myMinX = Min(myMinX,myX+dx) ;
386               myMinY = Min(myMinY,myY+dy) ;
387               myMaxX = Max(myMaxX,myX+dx) ;
388               myMaxY = Max(myMaxY,myY+dy) ;
389             } else {
390 #ifdef PRO14304
391               myMinX = Min(myMinX,myX+xmin) ;
392               myMinY = Min(myMinY,myY+ymin) ;
393               myMaxX = Max(myMaxX,myX+xmax) ;
394               myMaxY = Max(myMaxY,myY+ymax) ;
395 #else
396               myMinX = Min(myMinX,xmin) ;
397               myMinY = Min(myMinY,ymin) ;
398               myMaxX = Max(myMaxX,xmax) ;
399               myMaxY = Max(myMaxY,ymax) ;
400 #endif
401             }
402           }
403     }
404 #ifdef PERF
405       else {
406           cout << "*Graphic2d_FramedText::ComputeMinMax() returns wrong values*" << endl;
407    }
408 #endif
409
410     return status;
411 }
412
413 void Graphic2d_FramedText::Save(Aspect_FStream& aFStream) const
414 {
415 }