0023510: Integration of test grid "vis" into the new testing system
[occt.git] / src / V2d / V2d_View.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 /***********************************************************************
19  
20      FUNCTION :
21      ----------
22         Classe V2d_View :
23  
24      HISTORY OF MODIFICATIONS   :
25      --------------------------------
26       00-09-92 : GG  ; Creation.
27       13-11-97 : EUG ; ???????? New method Plot(...) 
28       06-01-98 : FMN ; BUC60065 
29       20-02-98 : STT ; S3558 
30       08-04-98 : STT ; suppr. S3558
31       24-03-98 : GG ; ?????? UseMFT()
32       26-03-98 : GG ; BUC60049 Add conversion method 
33                       View space -> Window pixel space
34       04-05-98 : GG ; PS driver PS is also usable under WNT
35       21-07-98 : DCB/SYL: Remove useless calls to SetXXXMap() methods
36       in PlotScreen ().
37       OCT-98   : DCB/SYL : ScreenCopy() method.
38       12-06-00 : TCL : new method Pick( Xmin, Ymin, Xmax, Ymax ) 
39       03-10-00 : TCL : new methods SetBackground(...)
40       14-11-01 : SAV : Added PickByCircle().
41       24-11-01 : SAV : SetBackground(...) overloaded.
42
43      NOTES :
44      -----------
45
46 ************************************************************************/
47
48 #define TRACE 0
49
50 #define PRO16111        //GG_021198
51 //                      Correction of method Fitall() that was wrong if 
52 //                      the window height was superior to the width
53
54 #define BUC60611        //VTN_291198
55 //                      Re change Fitall() computation method
56
57 #define IMP130300       //GG OPTIMIZATION The V2d_View::UpdateNew() method MUST use 
58 //                      Graphic2d_View::TinyUpdate() and no more Update()
59
60 #define JAP60249        //GG_131098
61 //                      Plots the view accordingly with the requested view center
62
63 #define IMP250500       //GG Update() the view after creation
64 //                      the driver of the view must be known before
65 //                      any minmax computation.
66
67 #define OCC540          //SAV Add Color( Quantity_Color& ) to retrieve background via RGB
68
69 /*----------------------------------------------------------------------*/
70 /*
71  * Includes
72  */
73
74 #include <V2d_View.ixx>
75 #include <Aspect_Window.hxx>
76 #include <Aspect_Units.hxx>
77 #include <Aspect_TypeOfResize.hxx>
78 #include <Graphic2d_Array1OfVertex.hxx>
79 #include <Graphic2d_Polyline.hxx>
80 #include <Graphic2d_Vertex.hxx>
81 #include <Graphic2d_Marker.hxx>
82 #include <Graphic2d_Text.hxx>
83 #include <TCollection_ExtendedString.hxx>
84 #include <V2d_DefaultMap.hxx>
85 #include <Graphic2d_CircleMarker.hxx>
86 #include <Aspect_GenericColorMap.hxx>
87 #include <Aspect_ColorMap.hxx>
88 #include <Aspect_ColorMapEntry.hxx>
89 #include <Quantity_Color.hxx>
90 #include <Aspect_Background.hxx>
91 #include <Quantity_Color.hxx>
92 #include <PS_Driver.hxx>
93 #include <Standard_ShortReal.hxx>
94 // S3603 - ScreenCopy ()
95 #include <Aspect_TypeMap.hxx>
96 #include <Aspect_WidthMap.hxx>
97 #include <Aspect_FontMap.hxx>
98 #include <Aspect_MarkMap.hxx>
99 #include <PlotMgt_ImageDriver.hxx>
100 #include <TColStd_HSequenceOfInteger.hxx>
101
102 //OCC186
103 #include <Standard_ErrorHandler.hxx>
104 #include <Standard_NumericError.hxx>
105 //OCC186
106
107 V2d_View::V2d_View(const Handle(Aspect_WindowDriver)& aWindowDriver,
108                    const Handle(V2d_Viewer)& aViewer,
109                    const Standard_Real aXCenter,
110                    const Standard_Real aYCenter,
111                    const Standard_Real aSize)
112
113 : myWindowDriver(aWindowDriver) ,
114   myViewer(aViewer.operator->()),
115   myFitallRatio (0.01) ,
116   myHitPoint(new Graphic2d_GraphicObject(aViewer->View())),
117   myHitBuf(new Graphic2d_Buffer(aViewer->View(),0.,0.))
118 {
119
120   myViewMapping = new Graphic2d_ViewMapping;
121   myViewMapping->SetViewMapping(aXCenter,aYCenter,aSize);
122   myViewMapping->SetViewMappingDefault();
123   myWindowDriver->WorkSpace(myWidth,myHeight);
124   this->MapToCenter();
125   myEnablePrevious = Standard_True;
126   this->StoreCurrent();
127   myDeflection = 0.0001 METER; // 10th of  millimeter at the screen.
128
129   aWindowDriver->SetColorMap(aViewer->ColorMap());
130   aWindowDriver->SetWidthMap(aViewer->WidthMap());
131   aWindowDriver->SetTypeMap (aViewer->TypeMap());
132   aWindowDriver->SetFontMap (aViewer->FontMap(),aViewer->UseMFT());
133   aWindowDriver->SetMarkMap (aViewer->MarkMap());
134   aViewer->AddView(this);
135 #ifdef IMP250500
136   Update();
137 #endif
138 }
139 void V2d_View::SetDefaultPosition(const Standard_Real aXCenter,
140                    const Standard_Real aYCenter,
141                    const Standard_Real aSize) {
142
143   myViewMapping->SetViewMapping(aXCenter,aYCenter,aSize);
144   myViewMapping->SetViewMappingDefault();
145   this->MapToCenter();
146   this->StoreCurrent();
147 }
148 void V2d_View::Fitall() {
149
150   this->StoreCurrent();
151   this->MapToCenter();
152
153   Quantity_Ratio rat = myWindowDriver->Window()->Ratio();
154
155   Quantity_Length XVMin,YVMin,XVMax,YVMax;
156   myViewer->View()->MinMax(XVMin,XVMax,YVMin,YVMax);
157   if(XVMin < ShortRealFirst() + 1. || YVMin < ShortRealFirst() + 1.) {
158     XVMin = ShortRealLast(); YVMin = ShortRealLast();    // Minmax are crossed, as
159     XVMax = ShortRealFirst();YVMax = ShortRealFirst();   // CAL does not do it!!!!!!!!!!!!
160   }
161
162   Quantity_Length XMMin,YMMin,XMMax,YMMax;
163   myViewer->View()->MarkerMinMax(XMMin,XMMax,YMMin,YMMax);
164   if(XMMin < ShortRealFirst() + 1. || YMMin < ShortRealFirst() + 1.) {
165     XMMin = ShortRealLast(); YMMin = ShortRealLast();    // Minmax are crossed, because 
166     XMMax = ShortRealFirst();YMMax = ShortRealFirst();   // CAL does not do it !!!!!!!!!!!!
167   }
168
169   Quantity_Length XMin = Min(XVMin,XMMin),YMin= Min(YVMin,YMMin),
170                   XMax = Max(XVMax,XMMax),YMax= Max(YVMax,YMMax);
171
172   Quantity_Length Xold,Yold,Sizeold;
173   myViewMapping->ViewMapping(Xold,Yold,Sizeold);
174
175 #ifdef PRO16111
176   Quantity_Length Xnew = Xold,Ynew = Yold,Sizenew = Sizeold;
177   Quantity_Length Dxnew = Sizeold, Dynew = Sizeold;
178   if( XMax > XMin ) {
179     Dxnew = XMax - XMin;
180     Xnew =  (XMax+XMin)/2.;
181   }
182   if( YMax > YMin ) {
183     Dynew = YMax - YMin;
184     Ynew =  (YMax+YMin)/2.;
185   }
186   if( rat >= 1. ) {
187 #ifdef BUC60611
188     if( Dxnew >= Dynew*rat ) Sizenew = Dxnew/2./rat;
189 #else
190     if( Dxnew >= Dynew ) Sizenew = Dxnew/2./rat;
191 #endif
192     else Sizenew = Dynew/2.;
193   } else {
194 #ifdef BUC60611
195     if( Dynew >= Dxnew/rat ) Sizenew = Dynew/2.*rat;
196     else Sizenew = Dxnew/2;
197 #else
198     if( Dxnew >= Dynew ) Sizenew = Dxnew/2.;
199     else Sizenew = Dynew/2.*rat;
200 #endif
201   }
202   Sizenew += Sizenew * myFitallRatio;
203 #else 
204   Quantity_Length Xnew,Ynew,Sizenew;
205   if ( XMin < XMax ) {
206     Xnew =  (XMax+XMin)/2.;
207     Sizenew = (XMax-XMin)/(1. - myFitallRatio)/2./rat;
208   }
209   else {
210     Xnew = Xold;
211     Sizenew = Sizeold;
212   }
213
214   if ( YMin <  YMax ) {
215     Ynew =  (YMax+YMin)/2.;
216     Sizenew = Max ( Sizenew , (YMax-YMin)/(1. - myFitallRatio)/2.);
217     }
218   else {
219     Ynew = Yold;
220     Sizenew = Max ( Sizenew , Sizeold);
221     }
222 #endif
223
224   myViewMapping->SetViewMapping( Xnew ,Ynew , Sizenew);
225   ImmediateUpdate();
226 }
227
228 void V2d_View::WindowFit(const Standard_Integer aX1,
229                    const Standard_Integer aY1,
230                    const Standard_Integer aX2,
231                    const Standard_Integer aY2) {
232  Fit(aX1,aY1,aX2,aY2);
233 }
234
235 void V2d_View::Fit(const Standard_Integer aX1,
236                    const Standard_Integer aY1,
237                    const Standard_Integer aX2,
238                    const Standard_Integer aY2) {
239
240   if( aX1 != aX2 && aY1 != aY2 ) {
241     this->MapToCenter();
242     Standard_Real x1,y1,x2,y2,xx1,yy1,xx2,yy2;
243     myWindowDriver->Convert(aX1,aY1,xx1,yy1);
244     myWindowDriver->Convert(aX2,aY2,xx2,yy2);
245     myViewer->View()->Convert(myViewMapping,xx1,yy1,myXPosition,myYPosition,myScale,x1,y1);
246     myViewer->View()->Convert(myViewMapping,xx2,yy2,myXPosition,myYPosition,myScale,x2,y2);
247     Fit(x1,y1,x2,y2,Standard_False);
248   }
249 }
250 void V2d_View::Fit(const Quantity_Length aX1,
251                    const Quantity_Length aY1,
252                    const Quantity_Length aX2,
253                    const Quantity_Length aY2,
254                    const Standard_Boolean UseMinimum) {
255
256   Viewer_BadValue_Raise_if( aX1 == aX2 || aY1 == aY2 ,"coordinates are confused");
257   this->StoreCurrent();
258   Quantity_Ratio rat = myWindowDriver->Window()->Ratio();
259   Quantity_Length XCenter, YCenter, Size;
260   XCenter = (aX1+aX2)/2.; YCenter = (aY1+aY2)/2.;
261   if (UseMinimum)
262     Size = Abs(aX2-aX1)/rat < Abs(aY2-aY1) ? Abs(aX2-aX1)/rat : Abs(aY2-aY1);
263   else
264     Size = Abs(aX2-aX1)/rat > Abs(aY2-aY1) ? Abs(aX2-aX1)/rat : Abs(aY2-aY1);
265
266   myViewMapping->SetViewMapping(XCenter,YCenter,Size/2.);
267 //OCC186
268   try {
269     ImmediateUpdate();
270   }
271   catch (Standard_NumericError) {
272     cout << "Exception caught during view Fit. " << endl;
273   }
274 //OCC186
275 }
276
277 void V2d_View::SetFitallRatio (const Standard_Real aRatio) {
278
279   Viewer_BadValue_Raise_if( aRatio < 0 || aRatio >=1 , 
280                             "ratio must be  more than 0. and less than 1.");
281   myFitallRatio = aRatio;
282
283 }
284 void V2d_View::Zoom (const Standard_Real Zoom) {
285   Viewer_BadValue_Raise_if(Zoom <= 0., "Zoom coefficient must be greater than 0.");
286   this->StoreCurrent();
287   Quantity_Length XCenter, YCenter, Size;
288
289   myViewMapping->ViewMapping(XCenter, YCenter, Size);
290   myViewMapping->SetViewMapping(XCenter,YCenter,Size/Zoom);
291
292 //OCC186
293   try {
294     ImmediateUpdate();
295   }
296   catch (Standard_NumericError) {
297     cout << "Exception caught during zooming! Zooming factor is too big." << endl;
298   }
299 //OCC186
300 }
301
302 void V2d_View::Zoom (const Standard_Integer aX1,
303                      const Standard_Integer aY1,
304                      const Standard_Integer aX2,
305                      const Standard_Integer aY2,
306                      const Quantity_Ratio aCoefficient) {
307   Standard_Real D = Abs(aX1-aX2) >= Abs(aY1-aY2) ? aX1-aX2 : aY2-aY1;
308   this->Zoom ( D > 0 ? ( 1. /(1. + aCoefficient * Abs(D))) 
309                : (1. + aCoefficient * Abs(D)));
310 }
311
312 void V2d_View::Zoom (const Standard_Integer aX,
313                      const Standard_Integer aY,
314                      const Quantity_Ratio aCoefficient) {
315
316   Standard_Integer Width, Height;
317   myWindowDriver->Window()->Size(Width, Height);
318   this->Zoom(Width/2,Height/2,aX,aY,aCoefficient);
319 }
320 void V2d_View::Magnify(const Handle(V2d_View)& anOriginView,
321                        const Standard_Integer X1,
322                        const Standard_Integer Y1,
323                        const Standard_Integer X2,
324                        const Standard_Integer Y2) {
325   Standard_Real x1,y1,x2,y2;
326   anOriginView->Convert(X1,Y1,x1,y1);
327   anOriginView->Convert(X2,Y2,x2,y2);
328   myViewMapping->SetViewMapping((x1+x2)/2.,(y1+y2)/2.,Max(x2-x1,y2-y1)/2.);
329   myViewMapping->SetViewMappingDefault();
330 //OCC186
331   try {
332     ImmediateUpdate();
333   }
334   catch (Standard_NumericError) {
335     cout << "Exception caught during view Magnify. " << endl;
336   }
337 //OCC186
338 }
339
340 void V2d_View::Translate (const Quantity_Length dx, const Quantity_Length dy) {
341
342   this->StoreCurrent();
343
344   Quantity_Length XCenter, YCenter;
345   myViewMapping->Center(XCenter, YCenter);
346   myViewMapping->SetCenter(XCenter+dx,YCenter+dy);
347
348 }
349
350 void V2d_View::Place (const Standard_Integer x, const Standard_Integer y,
351                       const Quantity_Length aZoomFactor) {
352   Quantity_Length xx,yy;
353   this->Convert(x,y,xx,yy);
354   this->ScreenPlace(xx,yy,aZoomFactor);
355 }
356 void V2d_View::ScreenPlace (const Quantity_Length x, const Quantity_Length y,
357                      const Quantity_Factor aZoomFactor)  {
358
359   this->StoreCurrent();
360   myViewMapping->SetCenter(x,y);
361   Zoom(aZoomFactor/Zoom());
362 }
363 void V2d_View::Pan (const Standard_Integer dx, const Standard_Integer dy) {
364
365   Standard_Real x,y;
366   x = myWindowDriver->Convert(dx);
367   y = myWindowDriver->Convert(dy);
368   Standard_Real xx,yy;
369   xx =   myViewer->View()->Convert(myViewMapping,x,myScale);
370   yy =   myViewer->View()->Convert(myViewMapping,y,myScale);
371   this->Translate(-xx,-yy);
372   ImmediateUpdate();
373 }
374
375 Quantity_Length V2d_View::Convert(const Standard_Integer V) const {
376
377   return myViewer->View()->Convert(myViewMapping,myWindowDriver->Convert(V),myScale);
378 }
379
380 void V2d_View::Convert (const Standard_Integer X, const Standard_Integer Y,
381                         Quantity_Length& ViewX, Quantity_Length& ViewY) 
382   const {
383
384   Standard_Real xx,yy;
385   myWindowDriver->Convert(X,Y,xx,yy);
386   myViewer->View()->Convert(myViewMapping,xx,yy,myXPosition,myYPosition,myScale,
387            ViewX,ViewY);
388 }
389
390 void V2d_View::Convert (const Quantity_Length ViewX, const Quantity_Length ViewY, Standard_Integer& X, Standard_Integer &Y)
391   const {
392
393   Standard_Real XCenter,YCenter,Size;
394   myViewMapping->ViewMapping(XCenter,YCenter,Size);
395   Standard_Real x = myXPosition + ((ViewX-XCenter)/Size) *myScale;
396   Standard_Real y = myYPosition + ((ViewY-YCenter)/Size) *myScale;
397   myWindowDriver->Convert(x,y,X,Y);
398 }
399
400 Quantity_Length V2d_View::Convert(const Quantity_Length DriverSize) const {
401   Quantity_Length X,Y,S;
402   myViewMapping->ViewMapping(X,Y,S);
403   return DriverSize / myScale * S;
404 }
405
406 void V2d_View::Reset () {
407
408   this->StoreCurrent();
409   this->MapToCenter();
410   myViewMapping->ViewMappingReset();
411   ImmediateUpdate();
412 }
413
414 Handle(Graphic2d_View) V2d_View::View () const {return myViewer->View();}
415
416 Handle(V2d_Viewer) V2d_View::Viewer () const {return myViewer;}
417
418 Handle(Aspect_WindowDriver) V2d_View::Driver() const {return myWindowDriver;}
419
420 void V2d_View::Update() const { 
421
422 //Augustin myWindowDriver->Window()->Clear();
423 //  EraseHit();
424   Quantity_Length XCenter, YCenter, Size;
425   myViewer->View()->SetTypeOfDeflection(Aspect_TOD_ABSOLUTE);
426   myViewMapping->ViewMapping(XCenter, YCenter, Size);
427   myViewer->View()->SetDeflection(myDeflection*Size/myScale);
428   myViewer->View()->Update(myWindowDriver,myViewMapping,myXPosition,myYPosition,myScale);}
429
430 void V2d_View::UpdateNew() const {
431
432 #ifdef IMP130300
433   myViewer->View()->TinyUpdate(myWindowDriver,myViewMapping,myXPosition,myYPosition,myScale,Standard_True);
434 #else
435   myViewer->View()->Update(myWindowDriver,myViewMapping,myXPosition,myYPosition,myScale,Standard_False);
436 #endif
437 }
438 void V2d_View::Restore() const { 
439
440   if(myWindowDriver->Window()->BackingStore()) 
441     myWindowDriver->Window()->Restore();
442   else 
443     this->Update();
444  }   
445
446 void V2d_View::RestoreArea (const Standard_Integer Xc,
447                             const Standard_Integer Yc,
448                             const Standard_Integer Width,
449                             const Standard_Integer Height) const {
450
451   if(myWindowDriver->Window()->BackingStore()) 
452     myWindowDriver->Window()->RestoreArea(Xc,Yc,Width,Height);
453   else 
454     this->Update();
455  }   
456         
457 void V2d_View::Dump() const { 
458  //myView->Update(new V2d_DumpDriver);
459 }
460
461 void V2d_View::Dump( const Standard_CString aFileName) const { 
462  myWindowDriver->Window()->Dump(aFileName); 
463 }
464
465 Handle(Graphic2d_DisplayList) V2d_View::Pick (
466                                 const Standard_Integer X,
467                                 const Standard_Integer Y,
468                                 const Standard_Integer aPrecision) {
469
470   Standard_Real x,y,xx,yy,prec;
471   myWindowDriver->Convert(X,Y,xx,yy);
472   prec =  myViewer->View()->Convert(myViewMapping,
473                           myWindowDriver->Convert(aPrecision),
474                           myScale);
475   myViewer->View()->Convert(myViewMapping,xx,yy,myXPosition,myYPosition,myScale,x,y);
476   return myViewer->View()->Pick(myViewMapping,x,y,prec,myXPosition,myYPosition,myScale);
477 }
478
479 //SAV
480 Handle(Graphic2d_DisplayList) V2d_View::PickByCircle( const Standard_Integer X,
481                                                       const Standard_Integer Y,
482                                                       const Standard_Integer Radius )
483 {
484   Standard_Real x, y, xx, yy, radius;
485   myWindowDriver->Convert(X,Y,xx,yy);
486   radius =  myViewer->View()->Convert( myViewMapping,
487                                        myWindowDriver->Convert( Radius ),
488                                        myScale );
489   myViewer->View()->Convert( myViewMapping,
490                              xx,yy, myXPosition, myYPosition, myScale, x, y );
491   return myViewer->View()->PickByCircle( myViewMapping, x, y, radius, 
492                                          myXPosition, myYPosition, myScale );
493 }
494
495 Handle(Graphic2d_DisplayList) V2d_View::Pick (
496                                 const Standard_Integer Xmin,
497                 const Standard_Integer Ymin,
498                 const Standard_Integer Xmax,
499                 const Standard_Integer Ymax,
500                 const Graphic2d_PickMode aPickMode ) {
501
502   Standard_Real x1, y1, xx1, yy1, x2, y2, xx2, yy2;
503   myWindowDriver->Convert( Xmin, Ymin, xx1, yy1 );
504   myWindowDriver->Convert( Xmax, Ymax, xx2, yy2 );
505
506   myViewer->View()->Convert( myViewMapping, xx1, yy1, myXPosition, myYPosition, myScale, x1, y1 );
507   myViewer->View()->Convert( myViewMapping, xx2, yy2, myXPosition, myYPosition, myScale, x2, y2 );
508
509   return myViewer->View()->Pick( myViewMapping, x1, y1, x2, y2, myXPosition, myYPosition, myScale, aPickMode );
510 }
511   
512 void V2d_View::Erase () { 
513   myViewer->View()->Erase();
514 }
515
516 void V2d_View::HasBeenMoved() {
517
518   myWindowDriver->ResizeSpace();
519 }
520
521 void V2d_View::MustBeResized(const V2d_TypeOfWindowResizingEffect anEffect) {
522
523   Standard_Real OldWidth = myWidth, OldHeight = myHeight;
524   Aspect_TypeOfResize TOR = myWindowDriver->ResizeSpace();
525   myWindowDriver->WorkSpace(myWidth,myHeight);
526   
527   switch (anEffect) {
528
529   case V2d_TOWRE_ENLARGE_SPACE: {
530     switch (TOR) {
531       case Aspect_TOR_UNKNOWN : break;
532       case Aspect_TOR_NO_BORDER : break;
533       case Aspect_TOR_TOP_BORDER :  break;
534       case Aspect_TOR_RIGHT_BORDER :  break;
535       case Aspect_TOR_BOTTOM_BORDER :  
536         myYPosition = myHeight - OldHeight + myYPosition;
537         break;
538       case Aspect_TOR_LEFT_BORDER : 
539         myXPosition = myWidth -  OldWidth  + myXPosition;
540         break;
541       case Aspect_TOR_TOP_AND_RIGHT_BORDER : break;
542       case Aspect_TOR_RIGHT_AND_BOTTOM_BORDER : 
543         myYPosition = myHeight - OldHeight + myYPosition;
544         break;
545       case Aspect_TOR_BOTTOM_AND_LEFT_BORDER : 
546         myXPosition = myWidth - OldWidth + myXPosition;
547         myYPosition = myHeight - OldHeight + myYPosition;
548         break;
549       case Aspect_TOR_LEFT_AND_TOP_BORDER: 
550         myXPosition = myWidth - OldWidth + myXPosition;
551         break;
552       }
553     break;
554   }
555   case V2d_TOWRE_ENLARGE_OBJECTS:{
556     
557     this->MapToCenter();
558     break;
559   }
560   }
561   this->StoreCurrent();
562   ImmediateUpdate();
563 }
564
565 void V2d_View::SetDefaultHighlightColor(const Standard_Integer aColorIndex) {
566
567   myViewer->View()->SetDefaultOverrideColor(aColorIndex);
568
569 }
570
571 #define SCREENCOPY_FILENAME "screencopy2d.gif"
572 #define NO_HILIGHT          0xFFFFFF
573 void V2d_View::ScreenCopy (const Handle(PlotMgt_PlotterDriver)& aPlotterDriver,
574                            const Standard_Boolean fWhiteBackground,
575                            const Quantity_Factor aPlotScale)
576 {
577   int i ;
578   TCollection_AsciiString aFileToDump;
579   Quantity_Factor    aScale;
580   Quantity_Length    thePixel;
581   Quantity_Parameter theWWidth, theWHeight;
582   Quantity_Parameter thePWidth, thePHeight;
583   Quantity_Length    aViewX, aViewY, aViewSize;
584   aPlotterDriver -> WorkSpace (thePWidth, thePHeight);
585   myWindowDriver -> WorkSpace (theWWidth, theWHeight);
586   myViewMapping  -> ViewMapping (aViewX, aViewY, aViewSize);
587   thePixel = myWindowDriver -> Convert (1);
588
589   if (theWWidth * theWHeight != 0.) {
590     if (aPlotScale == 0.) {
591       aScale = Min (thePWidth / theWWidth, thePHeight / theWHeight);
592     } else {
593       aScale = aPlotScale;
594       aScale *= (aViewSize / theWWidth); 
595     }
596     Quantity_Length aPlotX, aPlotY;
597     aPlotX = theWWidth  /2. * aScale;
598     aPlotY = theWHeight /2. * aScale;
599
600     // Set default maps (color, type, etc.) for plotter driver
601     aPlotterDriver -> SetColorMap ( new Aspect_GenericColorMap () );
602     aPlotterDriver -> SetTypeMap  ( new Aspect_TypeMap         () );
603     aPlotterDriver -> SetWidthMap ( new Aspect_WidthMap        () );
604     aPlotterDriver -> SetFontMap  ( new Aspect_FontMap         () );
605     aPlotterDriver -> SetMarkMap  ( new Aspect_MarkMap         () );
606     myViewer -> View() -> SetTypeOfDeflection (Aspect_TOD_ABSOLUTE);
607     myViewer -> View() -> SetDeflection       (myDeflection);
608   
609     // Set backgroung to white, unihiglight if any
610     Handle(TColStd_HSequenceOfInteger) theColors;
611     Handle(Graphic2d_DisplayList)      theDisplayList;
612     Aspect_Background theBack = myWindowDriver->Window()->Background();
613     if (fWhiteBackground)
614       myWindowDriver -> Window() -> SetBackground (Quantity_NOC_WHITE);
615     theDisplayList = myViewer -> View() -> DisplayList();
616     theColors      = new TColStd_HSequenceOfInteger ();
617     for ( i = 1; i <= theDisplayList -> Length(); i++) {
618       if (theDisplayList -> Value(i) -> IsHighlighted()) {
619         theColors -> Append (theDisplayList -> Value(i) -> OverrideColor());
620         theDisplayList -> Value(i) -> Display();
621       } else {
622         theColors -> Append (NO_HILIGHT);
623       }
624     }
625     Update ();
626
627     // Dump the view
628     if (aPlotterDriver->IsKind(STANDARD_TYPE(PlotMgt_ImageDriver))) {
629       aFileToDump  = aPlotterDriver->PlotFileName();
630     } else {
631       aFileToDump  = aPlotterDriver->SpoolDirectory();
632       aFileToDump += SCREENCOPY_FILENAME;
633     }
634     myWindowDriver -> Window() -> Dump (aFileToDump.ToCString());
635
636     // Return background and highlight if any
637     for (i = 1; i <= theDisplayList -> Length(); i++)
638       if (theColors -> Value(i) != NO_HILIGHT)
639         theDisplayList -> Value(i) -> Highlight(theColors -> Value(i));
640     if (fWhiteBackground)
641       myWindowDriver -> Window() -> SetBackground (theBack);
642     Update ();
643
644     // Draw imagefile by plotter driver
645     aPlotterDriver -> SetPixelSize (thePixel);
646     aPlotterDriver -> BeginDraw ();
647     aPlotterDriver -> DrawImageFile (
648       aFileToDump.ToCString(), (float)aPlotX, (float)aPlotY, aScale);
649     aPlotterDriver -> EndDraw   ();
650   }
651 }
652 #undef NO_HILIGHT
653 #undef SCREENCOPY_FILENAME
654
655 void V2d_View::Plot(const Handle(PlotMgt_PlotterDriver)& aPlotterDriver,
656                     const Quantity_Length aXCenter,
657                     const Quantity_Length aYCenter,
658                     const Quantity_Factor aPlotScale) const
659 {
660   Quantity_Length                 PaperWidth,PaperHeight;
661   
662   aPlotterDriver->SetColorMap(myWindowDriver->ColorMap());
663   aPlotterDriver->SetTypeMap(myWindowDriver->TypeMap());
664   aPlotterDriver->SetWidthMap(myWindowDriver->WidthMap());
665   aPlotterDriver->SetFontMap(myWindowDriver->FontMap(),myWindowDriver->UseMFT());
666   aPlotterDriver->SetMarkMap(myWindowDriver->MarkMap());
667   myViewer->View()->SetTypeOfDeflection(Aspect_TOD_ABSOLUTE);
668   myViewer->View()->SetDeflection(myDeflection);
669   
670   aPlotterDriver->WorkSpace (PaperWidth,PaperHeight);
671   // size of the map to force set the required size 
672   Quantity_Length aViewX , aViewY , aViewSize;
673   myViewMapping -> ViewMapping ( aViewX, aViewY, aViewSize );
674   Quantity_Factor aScale = aViewSize * aPlotScale;
675
676   Quantity_Length aPlotX , aPlotY;
677 #ifdef JAP60249
678 //printf(" V2d_View::Plot(%f,%f,%f,%f,%f,%f,%f)\n",PaperWidth,PaperHeight,aXCenter,aYCenter,aPlotScale,aViewSize,aScale);
679   Handle(Graphic2d_ViewMapping) myPlotMapping = new Graphic2d_ViewMapping;
680   myPlotMapping->SetViewMapping(aXCenter,aYCenter,aViewSize);
681   aPlotX = /*aPlotScale * */PaperWidth/2.;
682   aPlotY = /*aPlotScale * */PaperHeight/2.;
683   myViewer->View()->Update(aPlotterDriver,myPlotMapping,aPlotX,aPlotY,aScale);
684 #else
685   // to place the bottom view to the left of the list and not in the middle  
686   if (myWidth < myHeight ){
687     aPlotX = aViewSize*aPlotScale;
688     aPlotY = aPlotX*myHeight/myWidth;
689     if (PaperWidth > PaperHeight)
690       aPlotX *= 2.;
691   } else {
692     aPlotY  = aViewSize*aPlotScale;
693     aPlotX  = aPlotY*myWidth/myHeight;  
694     if (PaperWidth < PaperHeight)
695       aPlotY *= 2.;
696   }
697
698   myViewer->View()->Update(aPlotterDriver,myViewMapping,aPlotX,aPlotY,aScale);
699 #endif
700
701 #if TRACE > 0
702   // info size paper 
703   cout << "V2d_View::Plot(Driver,centre X,Y,scale):CenterX" << aViewX << " Y " << aViewY << " Size=" << aViewSize 
704     << " ViewPosX=" << myXPosition << " ViewPosY=" << myYPosition 
705       << " VueX=" << myWidth << " VueY=" << myHeight 
706         << " PlotX=" << PaperWidth << " PlotY=" << PaperHeight
707           << " PlotScale=" << aPlotScale 
708             << " PosX=" << aPlotX << " Posy=" << aPlotY << " Scale " << aScale 
709               << endl ;
710 #endif
711 }
712
713 void V2d_View :: Plot (
714                   const Handle( PlotMgt_PlotterDriver )& aDriver,
715                   const Quantity_Factor          aScale
716                  ) const {
717 #if TRACE > 0
718  cout << "V2d_View::Plot(driver,scale) scale=" << aScale << endl  ;
719 #endif
720  Plot( aDriver, (Quantity_Length) 0., (Quantity_Length) 0., aScale);
721 }  
722
723 void V2d_View::PostScriptOutput(const Standard_CString aFile,
724                                 const Quantity_Length aWidth,
725                                 const Quantity_Length aHeight,
726                                 const Quantity_Length aXCenter,
727                                 const Quantity_Length aYCenter,
728                                 const Quantity_Factor aScale,
729                                 const Aspect_TypeOfColorSpace aTypeOfColorSpace) 
730   const {
731   Handle(PS_Driver) aPSDriver = new PS_Driver(aFile,aWidth,aHeight,aTypeOfColorSpace);
732 //  if(aTypeOfColorSpace != PS_TOCS_BlackAndWhite) 
733 //     aPSDriver->SetColorMap(myWindowDriver->ColorMap());
734   Plot(aPSDriver,aXCenter,aYCenter,aScale);
735 }
736
737 void V2d_View::PlotScreen(const Handle(PlotMgt_PlotterDriver)& aPlotterDriver) const {
738  
739   // recuperate size paper
740   Quantity_Length PaperWidth,PaperHeight;
741   aPlotterDriver->WorkSpace(PaperWidth,PaperHeight);
742
743   // Determination size to fit all in the paper
744   Quantity_Length aViewX , aViewY , aViewSize;
745   Quantity_Length aViewSizeX , aViewSizeY;
746   Quantity_Length aPlotX , aPlotY;
747   Standard_Real aPlotScale;
748   myViewMapping -> ViewMapping ( aViewX, aViewY, aViewSize );
749   if (myWidth < myHeight ){
750     aViewSizeX = aViewSize;
751     aViewSizeY = aViewSizeX*myHeight/myWidth;
752   }else {
753     aViewSizeY = aViewSize;
754     aViewSizeX = aViewSizeY*myWidth/myHeight;  
755   }
756   aPlotX = PaperWidth /2./aViewSizeX;
757   aPlotY = PaperHeight/2./aViewSizeY;
758   aPlotScale = (aPlotX < aPlotY  ? aPlotX : aPlotY );
759
760   Quantity_Length aXCenter, aYCenter;
761   this->Center(aXCenter, aYCenter);
762
763 #if TRACE > 0
764   cout << "V2d_View::PlotScreen(Driver):Centre X=" << aViewX << " Y=" << aViewY << " Size=" << aViewSize   
765       << " SizeX=" << aViewSizeX << " Y=" << aViewSizeY 
766         << " PlotX=" << PaperWidth << " Y=" << PaperHeight        
767           << " PlotScaleX=" << aPlotX << " Y=" << aPlotY 
768             << " => PlotScale=" << aPlotScale 
769               << endl ;  
770 #endif
771
772   this->Plot(aPlotterDriver,aXCenter,aYCenter,aPlotScale);
773
774 }
775
776 void V2d_View::ScreenPostScriptOutput(const Standard_CString aFile,
777                                 const Quantity_Length aWidth,
778                                 const Quantity_Length aHeight,
779                                 const Aspect_TypeOfColorSpace aTypeOfColorSpace)
780  const {
781   Handle(PS_Driver) aPSDriver = new PS_Driver(aFile,aWidth,aHeight,aTypeOfColorSpace);
782 //  if(aTypeOfColorSpace != PS_TOCS_BlackAndWhite) 
783 //     aPSDriver->SetColorMap(myWindowDriver->ColorMap());
784   PlotScreen(aPSDriver);
785 }
786
787
788 void V2d_View::StoreCurrent () {
789
790   if(myEnablePrevious) {
791
792     myViewMapping->ViewMapping(myPreviousX,myPreviousY,myPreviousSize);
793     myPreviousXPosition = myXPosition;
794     myPreviousYPosition = myYPosition;
795     myPreviousScale = myScale;
796   }
797
798 }
799 void V2d_View::Previous () {
800
801   if(myEnablePrevious) {
802     Standard_Real x,y,s,a,b,c;
803     x = myPreviousX;
804     y = myPreviousY;
805     s = myPreviousSize;
806     a = myPreviousXPosition;
807     b = myPreviousYPosition;
808     c = myPreviousScale;
809     this->StoreCurrent();
810     myViewMapping->SetViewMapping(x,y,s);
811     myXPosition = a;
812     myYPosition = b;
813     myScale = c;
814   }
815   ImmediateUpdate();
816 }
817 void V2d_View::SetDeflection (const Quantity_Length aDeflection) {
818
819   myDeflection = aDeflection;
820
821 }
822
823 Quantity_Length V2d_View::Deflection() const { 
824
825   return myDeflection; 
826 }
827
828 void V2d_View::EnableStorePrevious () {myEnablePrevious = Standard_True;}
829
830 void V2d_View::DisableStorePrevious () {
831
832 this->StoreCurrent();
833 myEnablePrevious = Standard_False;}
834
835
836 void V2d_View::MapToCenter () {
837
838    myXPosition =  myWidth  /2.;
839    myYPosition =  myHeight /2.;
840    myScale     = ( (myWidth<myHeight) ? myWidth : myHeight ) /2.; 
841
842 }
843 Quantity_Factor V2d_View::Zoom () const {
844   return 1./myViewMapping->Zoom();
845 }
846
847 void V2d_View::Center (Quantity_Length& aX, Quantity_Length& aY) const {
848   myViewMapping->Center(aX,aY);
849 }
850
851 Quantity_Length V2d_View::Size() const {
852   Quantity_Length XCenter, YCenter, Size;
853   myViewMapping->ViewMapping(XCenter, YCenter, Size);
854   return Size;
855 }
856
857 Quantity_NameOfColor V2d_View::Color () const {
858   return myWindowDriver->Window()->Background().Color().Name();
859 }
860
861 void V2d_View::Color( Quantity_Color& color ) const
862 {
863 #ifdef OCC540
864   color.Assign( myWindowDriver->Window()->Background().Color() );
865 #endif
866 }
867
868 void V2d_View::Hit(const Standard_Integer X,
869                    const Standard_Integer Y,
870                    Quantity_Length& gx,
871                    Quantity_Length& gy) const {
872
873   Standard_Real rx,ry;
874   Convert(X,Y,rx,ry);
875   myViewer->Hit(rx,ry,gx,gy);
876 }
877
878 void V2d_View::ShowHit(const Standard_Integer X,
879                    const Standard_Integer Y) {
880   Standard_Real rx,ry,gx,gy;
881   Convert(X,Y,rx,ry);
882   myViewer->Hit(rx,ry,gx,gy);
883
884   myHitPoint->RemovePrimitives();
885   Handle(Graphic2d_Marker) 
886     M = new Graphic2d_Marker(myHitPoint,
887                              myViewer->HitPointMarkerIndex(),
888                              gx,gy,
889                              0.002 METER,0.002 METER);
890   M->SetColorIndex(myViewer->HitPointColor());
891
892
893   Standard_Real HitTextX,HitTextY;
894   myViewer->View()->Convert(myViewMapping,0.,0.,myXPosition,myYPosition,myScale,HitTextX,HitTextY);
895   Handle(Graphic2d_Text)
896    T1 = new Graphic2d_Text(myHitPoint,
897                            TCollection_ExtendedString(gx),
898                            HitTextX,HitTextY,0.);
899   T1->SetColorIndex(myViewer->CoordinatesColor());
900   T1->SetOffset(0. METER,0.005 METER);
901   T1->SetZoomable(Standard_False); //BUC50093
902   Handle(Graphic2d_Text)
903     T2 = new Graphic2d_Text(myHitPoint,
904                            TCollection_ExtendedString(gy),
905                             HitTextX,HitTextY,0.);
906   T2->SetColorIndex(myViewer->CoordinatesColor());
907   T2->SetZoomable(Standard_False); //BUC50093
908 //if(myHitPoint->IsDisplayed()) myHitPoint->Erase();
909 //myHitPoint->Display();
910   if(myHitBuf->IsPosted()) myHitBuf->UnPost();
911   myHitBuf->Clear();
912   myHitBuf->Add(myHitPoint);
913   myHitBuf->Post();
914 }
915
916 void V2d_View::EraseHit() {
917 //  if(myHitPoint->IsDisplayed()) myHitPoint->Erase();
918   if(myHitBuf->IsPosted()) myHitBuf->UnPost();
919 }  
920 void V2d_View::Scroll(Standard_Integer& dxc, Standard_Integer& dyc,
921                  Standard_Integer& lx, Standard_Integer& ly) {
922
923
924   Standard_Boolean Case = lx > 0 ? Standard_True: Standard_False; //war
925 // Case = Standard_false: there are only markers at the position 0,0;
926 // Case = Standard_True:  works properly only if there is nothing but geometry.
927
928   lx = Abs(lx);  // war
929
930   Quantity_Length XCenter, YCenter, Size;
931   myViewMapping->ViewMapping(XCenter, YCenter, Size);
932
933
934   Convert( - dxc , - dyc ,pxmin,pymax);
935   Convert( - dxc + lx, - dyc + ly ,pxmax,pymin);
936
937
938   Quantity_Length XMin,YMin,XMax,YMax;
939   myViewer->View()->MinMax(XMin,XMax,YMin,YMax);
940
941   dxc = 0;
942   dyc = 0;
943
944   if(XMin <= XMax && YMin <= YMax) { // empty view
945
946 // warning !!!
947     if(!Case) {
948       XMin = XMin  / myScale * Size;
949       XMax = XMax  / myScale * Size;
950       YMin = YMin  / myScale * Size;
951       YMax = YMax  / myScale * Size;
952     }
953 // end war
954
955     Standard_Boolean t = Standard_False;
956
957     if (XMin < pxmin) {
958       Standard_Real dx = XMin - pxmin;
959       Translate(dx,0);
960       Standard_Real ddx = dx  /Size * myScale; 
961       dxc = myWindowDriver->Convert(ddx);
962       t = Standard_True;
963     }
964     else
965       XMin = pxmin;
966     
967     if (YMax > pymax) {
968       Standard_Real dy = YMax - pymax;
969       Translate(0,dy);
970       Standard_Real ddy = dy  /Size * myScale; 
971       dyc = myWindowDriver->Convert(ddy);
972       t = Standard_True;
973     }    
974     else
975       YMax = pymax;
976     
977     if (XMax < pxmax) XMax = pxmax;
978     if (YMin > pymin) YMin = pymin;
979     
980     if(t) ImmediateUpdate();
981
982     Standard_Real a = (XMax - XMin)/Size * myScale; 
983     Standard_Real b = (YMax - YMin)/Size * myScale; 
984     
985     
986     lx = myWindowDriver->Convert(a);
987     ly = myWindowDriver->Convert(b);
988   }
989 }
990
991
992 Standard_Integer V2d_View::DefaultHighlightColor() const {
993 Standard_Integer index = 
994         (myViewer->View()->IsDefinedColor()) ?
995         myViewer->View()->DefaultOverrideColor() : -1;
996
997   return index;
998 }
999
1000 void V2d_View::SetBackground(const Quantity_NameOfColor aNameColor) {
1001
1002    myWindowDriver->Window()->SetBackground( aNameColor );
1003 }
1004
1005 Standard_Boolean V2d_View::SetBackground( const Standard_CString aNameFile,
1006                                           const Aspect_FillMethod aMethod ) {
1007
1008   return myWindowDriver->Window()->SetBackground(aNameFile,aMethod);
1009
1010 }
1011
1012 void V2d_View::SetBackground( const Quantity_Color& color )
1013 {
1014   myWindowDriver->Window()->SetBackground( color );
1015 }