ac083a5ed613419a57e3c1934e272dcd981103de
[scilab.git] / scilab / modules / renderer / src / cpp / subwinDrawing / ConcreteDrawableSubwin.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Jean-Baptiste Silvy
4  * Copyright (C) 2010 - Paul Griffiths
5  * desc : Class containing drivers independent routines for a subwin object
6  *
7  * This file must be used under the terms of the CeCILL.
8  * This source file is licensed as described in the file COPYING, which
9  * you should have received as part of this distribution.  The terms
10  * are also available at
11  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
12  *
13  */
14
15 #include "ConcreteDrawableSubwin.hxx"
16 #include "getHandleDrawer.h"
17 #include "BasicAlgos.hxx"
18
19 extern "C"
20 {
21 #include "GetProperty.h"
22 #include "SetProperty.h"
23 #include "pixel_mode.h"
24 #include "DrawingBridge.h"
25 #include "math_graphics.h"
26 }
27
28 using namespace std;
29
30 namespace sciGraphics
31 {
32
33 /*------------------------------------------------------------------------------------------*/
34 ConcreteDrawableSubwin::ConcreteDrawableSubwin(sciPointObj * pObj)
35   : DrawableSubwin(pObj)
36 {
37   m_pXBoundsStrategy = NULL;
38   m_pYBoundsStrategy = NULL;
39   m_pZBoundsStrategy = NULL;
40   m_pXTicksDrawer = NULL;
41   m_pYTicksDrawer = NULL;
42   m_pZTicksDrawer = NULL;
43
44   m_oAxesBoxDrawers.clear();
45
46 }
47 /*------------------------------------------------------------------------------------------*/
48 ConcreteDrawableSubwin::~ConcreteDrawableSubwin(void)
49 {
50
51   setXBoundsStrategy(NULL);
52   setYBoundsStrategy(NULL);
53   setZBoundsStrategy(NULL);
54
55   setXTicksDrawer(NULL);
56   setYTicksDrawer(NULL);
57   setZTicksDrawer(NULL);
58
59   removeAxesBoxDrawers();
60
61   m_oDisplayedTexts.clear();
62 }
63 /*------------------------------------------------------------------------------------------*/
64 void ConcreteDrawableSubwin::setXBoundsStrategy(ComputeBoundsStrategy * strategy)
65 {
66   if (m_pXBoundsStrategy != NULL)
67   {
68     delete m_pXBoundsStrategy;
69   }
70   m_pXBoundsStrategy = strategy;
71 }
72 /*------------------------------------------------------------------------------------------*/
73 void ConcreteDrawableSubwin::setYBoundsStrategy(ComputeBoundsStrategy * strategy)
74 {
75   if (m_pYBoundsStrategy != NULL)
76   {
77     delete m_pYBoundsStrategy;
78   }
79   m_pYBoundsStrategy = strategy;
80 }
81 /*------------------------------------------------------------------------------------------*/
82 void ConcreteDrawableSubwin::setZBoundsStrategy(ComputeBoundsStrategy * strategy)
83 {
84   if (m_pZBoundsStrategy != NULL)
85   {
86     delete m_pZBoundsStrategy;
87   }
88   m_pZBoundsStrategy = strategy;
89 }
90 /*------------------------------------------------------------------------------------------*/
91 void ConcreteDrawableSubwin::setXTicksDrawer(TicksDrawer * xTicksDrawer)
92 {
93   if(m_pXTicksDrawer != NULL)
94   {
95     delete m_pXTicksDrawer;
96   }
97   m_pXTicksDrawer = xTicksDrawer;
98 }
99 /*------------------------------------------------------------------------------------------*/
100 void ConcreteDrawableSubwin::setYTicksDrawer(TicksDrawer * yTicksDrawer)
101 {
102   if(m_pYTicksDrawer != NULL)
103   {
104     delete m_pYTicksDrawer;
105   }
106   m_pYTicksDrawer = yTicksDrawer;
107 }
108 /*------------------------------------------------------------------------------------------*/
109 void ConcreteDrawableSubwin::setZTicksDrawer(TicksDrawer * zTicksDrawer)
110 {
111   if(m_pZTicksDrawer != NULL)
112   {
113     delete m_pZTicksDrawer;
114   }
115   m_pZTicksDrawer = zTicksDrawer;
116 }
117 /*------------------------------------------------------------------------------------------*/
118 void ConcreteDrawableSubwin::addAxesBoxDrawer(DrawAxesBoxStrategy * strategy)
119 {
120   m_oAxesBoxDrawers.push_back(strategy);
121 }
122 /*------------------------------------------------------------------------------------------*/
123 void ConcreteDrawableSubwin::removeAxesBoxDrawers(void)
124 {
125   list<DrawAxesBoxStrategy *>::iterator it = m_oAxesBoxDrawers.begin();
126   for( ; it != m_oAxesBoxDrawers.end(); it++ )
127   {
128     delete *it;
129     *it = NULL;
130   }
131   m_oAxesBoxDrawers.clear();
132 }
133 /*------------------------------------------------------------------------------------------*/
134 void ConcreteDrawableSubwin::pointScale(double xCoord, double yCoord, double zCoord,
135                                         double * xScaled, double * yScaled, double * zScaled)
136 {
137   if (xScaled != NULL) { m_pXBoundsStrategy->pointScale(xCoord, xScaled); }
138   if (yScaled != NULL) { m_pYBoundsStrategy->pointScale(yCoord, yScaled); }
139   if (zScaled != NULL) { m_pZBoundsStrategy->pointScale(zCoord, zScaled); }
140 }
141 /*------------------------------------------------------------------------------------------*/
142 void ConcreteDrawableSubwin::inversePointScale(double xScaled, double yScaled, double zScaled,
143                                                double * xCoord, double * yCoord, double * zCoord)
144 {
145   if (xCoord != NULL) { m_pXBoundsStrategy->inversePointScale(xScaled, xCoord); }
146   if (yCoord != NULL) { m_pYBoundsStrategy->inversePointScale(yScaled, yCoord); }
147   if (zCoord != NULL) { m_pZBoundsStrategy->inversePointScale(zScaled, zCoord); }
148 }
149 /*------------------------------------------------------------------------------------------*/
150 void ConcreteDrawableSubwin::pointScale(double vectorX[], double vectorY[], double vectorZ[], int vectorLength)
151 {
152   if (vectorX != NULL) { m_pXBoundsStrategy->pointScale(vectorX, vectorLength); }
153   if (vectorY != NULL) { m_pYBoundsStrategy->pointScale(vectorY, vectorLength); }
154   if (vectorZ != NULL) { m_pZBoundsStrategy->pointScale(vectorZ, vectorLength); }
155 }
156 /*------------------------------------------------------------------------------------------*/
157 void ConcreteDrawableSubwin::directionScale(double xCoord, double yCoord, double zCoord,
158                                             double startingPointX, double startingPointY, double startingPointZ,
159                                             double * xScaled, double * yScaled, double * zScaled)
160 {
161   if (xScaled != NULL) { m_pXBoundsStrategy->directionScale(xCoord, startingPointX, xScaled); }
162   if (yScaled != NULL) { m_pYBoundsStrategy->directionScale(yCoord, startingPointY, yScaled); }
163   if (zScaled != NULL) { m_pZBoundsStrategy->directionScale(zCoord, startingPointZ, zScaled); }
164 }
165 /*------------------------------------------------------------------------------------------*/
166 void ConcreteDrawableSubwin::directionScale(double vectorX[], double vectorY[], double vectorZ[],
167                                             double startingPointsX[], double startingPointsY[],
168                                             double startingPointsZ[], double vectorLength)
169 {
170   if (vectorX != NULL) { m_pXBoundsStrategy->directionScale(vectorX, startingPointsX, vectorLength); }
171   if (vectorY != NULL) { m_pYBoundsStrategy->directionScale(vectorY, startingPointsY, vectorLength); }
172   if (vectorZ != NULL) { m_pZBoundsStrategy->directionScale(vectorZ, startingPointsZ, vectorLength); }
173 }
174 /*------------------------------------------------------------------------------------------*/
175 void ConcreteDrawableSubwin::computeRealDataBounds(void)
176 {
177   // retrieve user bounds
178   double userBounds[6];
179   sciGetDisplayedDataBounds(m_pDrawed, userBounds);
180
181   // check whether the subwin is zoomed or not
182   bool isZoomed = (sciGetZooming(m_pDrawed) == TRUE);
183
184   // check whether tight limits are enabled or not
185   bool tightLimitsEnabled = (sciGetTightLimitsOn(m_pDrawed) == TRUE);
186
187   double bestBounds[6]; // output bounds
188
189   // take sub arrays
190   double * userXBounds = userBounds;
191   double * userYBounds = userBounds + 2;
192   double * userZBounds = userBounds + 4;
193
194   double * bestXBounds = bestBounds;
195   double * bestYBounds = bestBounds + 2;
196   double * bestZBounds = bestBounds + 4;
197
198   // apply scale
199   m_pXBoundsStrategy->applyScaleModification(userXBounds, bestXBounds);
200   m_pYBoundsStrategy->applyScaleModification(userYBounds, bestYBounds);
201   m_pZBoundsStrategy->applyScaleModification(userZBounds, bestZBounds);
202
203   // if the X axis are origin and we are not in zoom mode
204   // we need to add 0
205   if (pSUBWIN_FEATURE(m_pDrawed)->axes.xdir == 'o' && !isZoomed) {
206     addZeroInRange(bestYBounds);
207   }
208
209   // same for Y axis
210   if (pSUBWIN_FEATURE(m_pDrawed)->axes.ydir == 'o' && !isZoomed) {
211     addZeroInRange(bestXBounds);
212   }
213
214   // fit them if needed
215   // for a more accurate zoom, tight limits are enabled if the zoom
216   // is enabled
217   if (!tightLimitsEnabled && !isZoomed)
218   {
219     m_pXBoundsStrategy->applyBestFitting(bestXBounds, bestXBounds);
220     m_pYBoundsStrategy->applyBestFitting(bestYBounds, bestYBounds);
221     m_pZBoundsStrategy->applyBestFitting(bestZBounds, bestZBounds);
222   }
223
224   /* If tight limits are enabled, check whether the min and max bounds are equal,
225   for each of the 3 axes; in this case, the automatically computed bounds are kept */
226   if (tightLimitsEnabled && !isZoomed)
227   {
228     if(SAFE_EQUAL(bestXBounds[0], bestXBounds[1], BOUNDS_COMPARE_ACCURACY))
229     {
230       m_pXBoundsStrategy->applyBestFitting(bestXBounds, bestXBounds);
231     }
232
233     if(SAFE_EQUAL(bestYBounds[0], bestYBounds[1], BOUNDS_COMPARE_ACCURACY))
234     {
235       m_pYBoundsStrategy->applyBestFitting(bestYBounds, bestYBounds);
236     }
237
238     if(SAFE_EQUAL(bestZBounds[0], bestZBounds[1], BOUNDS_COMPARE_ACCURACY))
239     {
240       m_pZBoundsStrategy->applyBestFitting(bestZBounds, bestZBounds);
241     }
242   }
243
244   //sciSetRealDataBounds(m_pDrawed, bestBounds);
245
246 }
247 /*------------------------------------------------------------------------------------------*/
248 void ConcreteDrawableSubwin::updateScale(void)
249 {
250
251   if (!m_bNeedCoordUpdate) {
252     // no need to update
253     return;
254   }
255
256         // to be sure that the inner structure is up to date.
257         update();
258
259   sciPointObj * parentFigure = sciGetParentFigure(m_pDrawed);
260   BOOL visible = sciGetVisibility(m_pDrawed);
261   int pixelMode = sciGetXorMode(parentFigure);
262
263
264   // update the data by just calling
265   // display on the invisible window
266   //sciSetXorMode(parentFigure, getPixelModeIndex("noop"));
267   //sciSetVisibility(m_pDrawed, FALSE);
268   //sciDrawSingleObj(m_pDrawed);
269   //sciSetVisibility(m_pDrawed, visible);
270   //sciSetXorMode(parentFigure, pixelMode);
271 }
272 /*------------------------------------------------------------------------------------------*/
273 int ConcreteDrawableSubwin::getNbXTicks(void)
274 {
275         // to be sure that the inner structure is up to date.
276         update();
277
278   if (m_pXTicksDrawer != NULL)
279   {
280     return m_pXTicksDrawer->getInitNbTicks();
281   }
282   else
283   {
284     return 0;
285   }
286 }
287 /*------------------------------------------------------------------------------------------*/
288 void ConcreteDrawableSubwin::getXTicksPos(double ticksPositions[], char ** ticksLabels)
289 {
290         // to be sure that the inner structure is up to date.
291         update();
292
293   if (m_pXTicksDrawer != NULL)
294   {
295     m_pXTicksDrawer->getInitTicksPos(ticksPositions, ticksLabels);
296
297     // revert log scale if needed
298     m_pXBoundsStrategy->inversePointScale(ticksPositions, getNbXTicks());
299   }
300 }
301 /*------------------------------------------------------------------------------------------*/
302 int ConcreteDrawableSubwin::getNbYTicks(void)
303 {
304         // to be sure that the inner structure is up to date.
305         update();
306
307   if (m_pYTicksDrawer != NULL)
308   {
309     return m_pYTicksDrawer->getInitNbTicks();
310   }
311   else
312   {
313     return 0;
314   }
315 }
316 /*------------------------------------------------------------------------------------------*/
317 void ConcreteDrawableSubwin::getYTicksPos(double ticksPositions[], char ** ticksLabels)
318 {
319         // to be sure that the inner structure is up to date.
320         update();
321
322   if (m_pYTicksDrawer != NULL)
323   {
324     m_pYTicksDrawer->getInitTicksPos(ticksPositions, ticksLabels);
325
326     // revert log scale if needed
327     m_pYBoundsStrategy->inversePointScale(ticksPositions, getNbYTicks());
328   }
329 }
330 /*------------------------------------------------------------------------------------------*/
331 int ConcreteDrawableSubwin::getNbZTicks(void)
332 {
333         // to be sure that the inner structure is up to date.
334         update();
335
336   if (m_pZTicksDrawer != NULL)
337   {
338     return m_pZTicksDrawer->getInitNbTicks();
339   }
340   else
341   {
342     return 0;
343   }
344 }
345 /*------------------------------------------------------------------------------------------*/
346 void ConcreteDrawableSubwin::getZTicksPos(double ticksPositions[], char ** ticksLabels)
347 {
348         // to be sure that the inner structure is up to date.
349         update();
350
351   if (m_pZTicksDrawer != NULL)
352   {
353     m_pZTicksDrawer->getInitTicksPos(ticksPositions, ticksLabels);
354
355     // revert log scale if needed
356     m_pZBoundsStrategy->inversePointScale(ticksPositions, getNbZTicks());
357   }
358 }
359 /*------------------------------------------------------------------------------------------*/
360 void ConcreteDrawableSubwin::getNbSubticksPerGrad(double nbsubtics[3])
361 {
362   // to be sure that the inner structure is up to date.
363   update();
364
365   // Initialize all elements to -1.
366   nbsubtics[0] = nbsubtics[1] = nbsubtics[2] = -1;
367
368   if (m_pXTicksDrawer != NULL)
369     nbsubtics[0] =  m_pXTicksDrawer->getInitNbSubticksPerGrad();
370
371   if (m_pYTicksDrawer != NULL)
372     nbsubtics[1] =  m_pYTicksDrawer->getInitNbSubticksPerGrad();
373
374   if (m_pZTicksDrawer != NULL)
375     nbsubtics[2] =  m_pZTicksDrawer->getInitNbSubticksPerGrad();
376 }
377 /*------------------------------------------------------------------------------------------*/
378 bool ConcreteDrawableSubwin::getXAxisPosition(double axisStart[3], double axisEnd[3], double ticksDirection[3])
379 {
380
381   if (m_pXTicksDrawer != NULL)
382   {
383     m_pXTicksDrawer->getAxisPosition(axisStart, axisEnd, ticksDirection);
384     return true;
385   }
386   else
387   {
388     return false;
389   }
390 }
391 /*------------------------------------------------------------------------------------------*/
392 bool ConcreteDrawableSubwin::getYAxisPosition(double axisStart[3], double axisEnd[3], double ticksDirection[3])
393 {
394   if (m_pYTicksDrawer != NULL)
395   {
396     m_pYTicksDrawer->getAxisPosition(axisStart, axisEnd, ticksDirection);
397     return true;
398   }
399   else
400   {
401     return false;
402   }
403 }
404 /*------------------------------------------------------------------------------------------*/
405 bool ConcreteDrawableSubwin::getZAxisPosition(double axisStart[3], double axisEnd[3], double ticksDirection[3])
406 {
407   if (m_pZTicksDrawer != NULL)
408   {
409     m_pZTicksDrawer->getAxisPosition(axisStart, axisEnd, ticksDirection);
410     return true;
411   }
412   else
413   {
414     return false;
415   }
416 }
417 /*------------------------------------------------------------------------------------------*/
418 void ConcreteDrawableSubwin::addTextToDraw(sciPointObj * text)
419 {
420         m_oDisplayedTexts.push_back(text);
421         textChanged();
422 }
423 /*------------------------------------------------------------------------------------------*/
424 void ConcreteDrawableSubwin::removeTextToDraw(sciPointObj * text)
425 {
426         m_oDisplayedTexts.remove(text);
427   textChanged();
428 }
429 /*------------------------------------------------------------------------------------------*/
430 void ConcreteDrawableSubwin::displayChildren(void)
431 {
432   // draw the children as usual
433   DrawableObject::displayChildren();
434
435   // because of transparency, the text is drawn after.
436   displayTexts();
437
438 }
439 /*------------------------------------------------------------------------------------------*/
440 void ConcreteDrawableSubwin::textChanged(void)
441 {
442   m_bTextListChanged = true;
443 }
444 /*------------------------------------------------------------------------------------------*/
445 void ConcreteDrawableSubwin::drawBox(void)
446 {
447   // If axes is not displayed m_pAxesbox is not drawn.
448   if (m_oAxesBoxDrawers.empty())
449   {
450     return ;
451   }
452
453   int concealedCornerIndex = computeConcealedCornerIndex();
454   list<DrawAxesBoxStrategy *>::iterator it = m_oAxesBoxDrawers.begin();
455   for ( ; it != m_oAxesBoxDrawers.end(); it++)
456   {
457     (*it)->drawAxesBox(concealedCornerIndex);
458   }
459 }
460 /*------------------------------------------------------------------------------------------*/
461 void ConcreteDrawableSubwin::drawTicks(void)
462 {
463   double distToXaxis = 0.0;
464   double distToYaxis = 0.0;
465   double distToZaxis = 0.0;
466
467   // Z ticks are deeper so draw them before
468   if (m_pZTicksDrawer != NULL)
469   {
470     distToZaxis = m_pZTicksDrawer->draw();
471   }
472   if (m_pYTicksDrawer != NULL)
473   {
474     distToYaxis = m_pYTicksDrawer->draw();
475   }
476   if (m_pXTicksDrawer != NULL)
477   {
478     distToXaxis = m_pXTicksDrawer->draw();
479   }
480
481   /* for title there is no displayable ticks */
482   setLabelsDistanceToAxis(distToXaxis, distToYaxis, distToZaxis, 0.0);
483 }
484 /*------------------------------------------------------------------------------------------*/
485 void ConcreteDrawableSubwin::showBox(void)
486 {
487   list<DrawAxesBoxStrategy *>::iterator it = m_oAxesBoxDrawers.begin();
488   for ( ; it != m_oAxesBoxDrawers.end(); it++)
489   {
490     (*it)->show();
491   }
492 }
493 /*------------------------------------------------------------------------------------------*/
494 void ConcreteDrawableSubwin::showTicks(void)
495 {
496   double distToXaxis = 0.0;
497   double distToYaxis = 0.0;
498   double distToZaxis = 0.0;
499   if (m_pXTicksDrawer != NULL)
500   {
501     distToXaxis = m_pXTicksDrawer->show();
502   }
503   if (m_pYTicksDrawer != NULL)
504   {
505     distToYaxis = m_pYTicksDrawer->show();
506   }
507   if (m_pZTicksDrawer != NULL)
508   {
509     distToZaxis = m_pZTicksDrawer->show();
510   }
511
512   /* for title there is no displayable ticks */
513   setLabelsDistanceToAxis(distToXaxis, distToYaxis, distToZaxis, 0.0);
514
515 }
516 /*------------------------------------------------------------------------------------------*/
517 void ConcreteDrawableSubwin::displayLabels(void)
518 {
519 #if 0
520   sciSons * curSon = sciGetLastSons( m_pDrawed ) ;
521
522   // there are 4 labels, stored at then end of the list
523   for (int i = 0; i < 4; i++)
524   {
525     getHandleDrawer(curSon->pointobj)->display();
526     curSon = curSon->pprev;
527   }
528 #endif
529 }
530 /*------------------------------------------------------------------------------------------*/
531 void ConcreteDrawableSubwin::displayTexts(void)
532 {
533   list<sciPointObj *> displayedTexts = m_oDisplayedTexts;
534   // sortDisplayed text if needed
535   if (m_bNeedDraw || m_bNeedRedraw || m_bTextListChanged)
536   {
537     displayedTexts.sort(getTextOrder);
538   }
539
540   // display all the text registered in the list
541   // The list should be sorted
542   list<sciPointObj *>::iterator it = displayedTexts.begin();
543   for ( ; it != displayedTexts.end(); it++)
544   {
545     // HACK here. This patch is to force disepearance
546     // of text objects if one of there parents is not visible.
547     if (sciGetRealVisibility(*it))
548     {
549       getHandleDrawer(*it)->display();
550     }
551   }
552 }
553 /*------------------------------------------------------------------------------------------*/
554 void ConcreteDrawableSubwin::setLabelsDistanceToAxis(double xLabelDist, double yLabelDist,
555                                                      double zLabelDist, double titleDist)
556 {
557   sciPointObj * xLabel = pSUBWIN_FEATURE(m_pDrawed)->mon_x_label;
558   getLabelDrawer(xLabel)->setDistanceToAxis(xLabelDist);
559
560   sciPointObj * yLabel = pSUBWIN_FEATURE(m_pDrawed)->mon_y_label;
561   getLabelDrawer(yLabel)->setDistanceToAxis(yLabelDist);
562
563   sciPointObj * zLabel = pSUBWIN_FEATURE(m_pDrawed)->mon_z_label;
564   getLabelDrawer(zLabel)->setDistanceToAxis(zLabelDist);
565
566   sciPointObj * titleLabel = pSUBWIN_FEATURE(m_pDrawed)->mon_title;
567   getLabelDrawer(titleLabel)->setDistanceToAxis(titleDist);
568 }
569 /*------------------------------------------------------------------------------------------*/
570 void ConcreteDrawableSubwin::addZeroInRange(double range[2]) {
571   if (range[0] > 0.0 && range[1] > 0.0) {
572   // both are greater than 0, so put the lowest to 0
573     range[0] = 0.0;
574   }
575   else if (range[0] < 0.0 && range[1] < 0.0) {
576   // both are lower than 0, so put the gretestt to 0
577     range[1] = 0.0;
578   }
579 }
580 /*------------------------------------------------------------------------------------------*/
581 int ConcreteDrawableSubwin::computeConcealedCornerIndex(void)
582 {
583   double bounds[6];
584   sciGetRealDataBounds(m_pDrawed, bounds);
585
586   Camera * cam = getCamera();
587
588   // eight conrners of the axes box
589   double corners[8][3];
590   for (int i = 0; i < 8; i++)
591   {
592     // compute position of corner i
593     corners[i][0] = (i < 4 ? bounds[0] : bounds[1]); // xMin or xMax
594     corners[i][1] = ((i % 4) < 2 ? bounds[2] : bounds[3]); // yMin or yMax
595     corners[i][2] = ((i % 2) == 0 ? bounds[4] : bounds[5]); // zMin or zMax
596
597     // directly convert it to pixel coordinates
598     cam->getPixelCoordinatesRaw(corners[i], corners[i]);
599   }
600
601   // fin the index of the deeper corner
602   double eyeDistance = corners[0][2];
603   int farthestCornerIndex = 0;
604   for (int i = 1; i < 8; i++) {
605     if (corners[i][2] > eyeDistance) {
606       eyeDistance = corners[i][2];
607       farthestCornerIndex = i;
608     }
609   }
610   return farthestCornerIndex;
611
612 }
613 /*---------------------------------------------------------------------------------*/
614 double ConcreteDrawableSubwin::getEyeDistance(Camera * cam, sciPointObj * pText)
615 {
616         // text is drawn flat so any point of the text has the same distance
617   // with the viewpoint. So let choose the text center.
618   double textPos[3];
619   sciGetTextPos(pText, textPos);
620
621   // convert it to pixel coordinate. Z value correspond to the depth.
622   cam->getPixelCoordinates(textPos, textPos);
623
624   return textPos[2];
625 }
626 /*---------------------------------------------------------------------------------*/
627 bool ConcreteDrawableSubwin::getTextOrder(sciPointObj * pText1, sciPointObj * pText2)
628 {
629         Camera * cam = getSubwinDrawer(sciGetParentSubwin(pText1))->getCamera();
630         // find the deepest witch is the first drawn.
631         return (getEyeDistance(cam, pText1) > getEyeDistance(cam, pText2));
632 }
633 /*---------------------------------------------------------------------------------*/
634 }