1 
2 
3 #include "tgl.h"
4 #include "tvectorgl.h"
5 #include "tregion.h"
6 #include "tregionprop.h"
7 #include "tstrokeutil.h"
8 #include "tvectorrenderdata.h"
9 #include "tvectorimage.h"
10 #include "tpalette.h"
11 #include "tcolorfunctions.h"
12 #include "tsimplecolorstyles.h"
13 #include "tthreadmessage.h"
14 #include "tstrokeprop.h"
15 
16 #include "tconvert.h"
17 #include "tcurves.h"
18 #include "tstrokeoutline.h"
19 #include <QTime>
20 
21 #ifndef _WIN32
22 #define CALLBACK
23 #endif
24 
25 #ifndef checkErrorsByGL
26 #define checkErrorsByGL                                                        \
27   {                                                                            \
28     GLenum err = glGetError();                                                 \
29     assert(err != GL_INVALID_ENUM);                                            \
30     assert(err != GL_INVALID_VALUE);                                           \
31     assert(err != GL_INVALID_OPERATION);                                       \
32     assert(err != GL_STACK_OVERFLOW);                                          \
33     assert(err != GL_STACK_UNDERFLOW);                                         \
34     assert(err != GL_OUT_OF_MEMORY);                                           \
35     assert(err == GL_NO_ERROR);                                                \
36   }
37 #endif
38 
39 #undef checkErrorsByGL
40 #define checkErrorsByGL
41 
42 using namespace std;
43 
44 //-----------------------------------------------------------------------------
45 /*
46 DV_EXPORT_API void mylog(std::string s)
47 {
48   static TThread::Mutex mutex;
49   QMutexLocker sl(mutex);
50   std::ofstream os("C:\\gmt\\buttami\\bu.txt", std::ios::app);
51 
52   LARGE_INTEGER ticksPerSecond;
53   LARGE_INTEGER tick;
54   static LARGE_INTEGER firstTick;
55   static bool firstTime = true;
56   long dt = 0;
57 
58   QueryPerformanceFrequency(&ticksPerSecond);
59   QueryPerformanceCounter(&tick);
60   if(firstTime) {firstTick = tick;firstTime=false;}
61   else
62   {
63     dt =
64 (long)(1000000*(tick.QuadPart-firstTick.QuadPart)/ticksPerSecond.QuadPart);
65   }
66   os << dt << ":" << s << std::endl;
67 }
68 */
69 
70 //=============================================================================
71 #ifdef _DEBUG
72 
checkQuadraticDistance(TStroke * stroke,bool checkThickness)73 bool checkQuadraticDistance(TStroke *stroke, bool checkThickness) {
74   UINT i, qCount = stroke->getChunkCount();
75   const TThickQuadratic *q;
76   TThickPoint p1, p2, p3;
77 
78   // se i punti coincidono e' una stroke puntiforme ed e' ammessa
79   if (qCount == 1) return true;
80 
81   for (i = 0; i != qCount; i++) {
82     q  = stroke->getChunk(i);
83     p1 = q->getThickP0();
84     p2 = q->getThickP1();
85     p3 = q->getThickP2();
86 
87     if (areAlmostEqual(p1.x, p2.x) && areAlmostEqual(p2.x, p3.x) &&
88         areAlmostEqual(p1.y, p2.y) && areAlmostEqual(p2.y, p3.y) &&
89         (!checkThickness || (areAlmostEqual(p1.thick, p2.thick) &&
90                              areAlmostEqual(p2.thick, p3.thick))))
91       return false;
92   }
93   return true;
94 }
95 
96 //-----------------------------------------------------------------------------
97 
drawControlPoints(const TVectorRenderData & rd,TStroke * stroke,double pixelSize,bool allPoints=true)98 void drawControlPoints(const TVectorRenderData &rd, TStroke *stroke,
99                        double pixelSize, bool allPoints = true) {
100   int i;
101   TPointD p;
102   glPushMatrix();
103 
104   tglMultMatrix(rd.m_aff);
105 
106   glPointSize(2.0);
107   glBegin(GL_POINTS);
108 
109   if (allPoints) {
110     int n = stroke->getControlPointCount();
111     for (i = 0; i < n; ++i) {
112       p = stroke->getControlPoint(i);
113       glColor3d((i + 1) & 1, i & 1, 0.0);
114       glVertex2d(p.x, p.y);
115     }
116   } else {
117     int n = stroke->getChunkCount();
118     for (i = 0; i < n; ++i) {
119       const TThickQuadratic *chunk = stroke->getChunk(i);
120       p                            = chunk->getP0();
121       glColor3d(1.0, 0.0, 0.0);
122       glVertex2d(p.x, p.y);
123     }
124     const TThickQuadratic *chunk = stroke->getChunk(n - 1);
125     glColor3d(1.0, 0.0, 0.0);
126     p = chunk->getP2();
127     glVertex2d(p.x, p.y);
128   }
129 
130   glEnd();
131   glPopMatrix();
132 }
133 
134 #endif
135 
136 //-----------------------------------------------------------------------------
137 
drawArrows(TStroke * stroke,bool onlyFirstPoint)138 static void drawArrows(TStroke *stroke, bool onlyFirstPoint) {
139   double length = stroke->getLength(0.0, 1.0);
140   int points    = length / 20;
141   if (points < 2) points += 1;
142   double currentPosition = 0.0;
143 
144   TPointD prePoint, point, postPoint;
145   glColor3d(1.0, 0.0, 0.0);
146   for (int i = 0; i <= points; i++) {
147     currentPosition = i / (double)points;
148     point           = stroke->getPointAtLength(length * currentPosition);
149     prePoint =
150         (i == 0) ? point
151                  : stroke->getPointAtLength(length * (currentPosition - 0.02));
152     postPoint =
153         (i == points)
154             ? point
155             : stroke->getPointAtLength(length * (currentPosition + 0.02));
156 
157     if (prePoint == postPoint) continue;
158 
159     double radian =
160         std::atan2(postPoint.y - prePoint.y, postPoint.x - prePoint.x);
161     double degree = radian * 180.0 / 3.14159265;
162 
163     glPushMatrix();
164     glTranslated(point.x, point.y, 0);
165     glRotated(degree, 0, 0, 1);
166     glBegin(GL_LINES);
167     glVertex2d(0, 0);
168     glVertex2d(-3, -3);
169     glVertex2d(0, 0);
170     glVertex2d(-3, 3);
171     glEnd();
172     glPopMatrix();
173 
174     if (onlyFirstPoint) break;
175     // make the arrow blue from the second one
176     glColor3d(0.0, 0.0, 1.0);
177   }
178 }
179 
180 //-----------------------------------------------------------------------------
181 // Used for Guided Drawing
drawFirstControlPoint(const TVectorRenderData & rd,TStroke * stroke)182 static void drawFirstControlPoint(const TVectorRenderData &rd,
183                                   TStroke *stroke) {
184   TPointD p          = stroke->getPoint(0.0);
185   double length      = stroke->getLength(0.0, 1.0);
186   int msecs          = QTime::currentTime().msec();
187   double modifier    = (msecs / 100) * 0.1;
188   TPointD startPoint = stroke->getPointAtLength(length * modifier);
189   TPointD endPoint   = stroke->getPointAtLength(length * 0.10);
190   double j           = 0.025;
191 
192   glPushMatrix();
193   tglMultMatrix(rd.m_aff);
194   if (!rd.m_animatedGuidedDrawing) glLineWidth(2.0f);
195   glColor3d(0.0, 1.0, 0.0);
196   if (!rd.m_animatedGuidedDrawing) {
197     drawArrows(stroke, false);
198   }
199 
200   if (rd.m_animatedGuidedDrawing) {
201     drawArrows(stroke, true);
202     glColor3d(0.0, 1.0, 0.0);
203     j = 0.025 + modifier;
204     glBegin(GL_LINES);
205     // draw the first animated section
206     for (int i = 0; i < 8; i++) {
207       endPoint = stroke->getPointAtLength(length * j);
208       glVertex2d(startPoint.x, startPoint.y);
209       glVertex2d(endPoint.x, endPoint.y);
210       startPoint = endPoint;
211       j += 0.025;
212       if (j > 1) {
213         j -= 1;
214         startPoint = stroke->getPointAtLength(length * j);
215       }
216     }
217 
218     modifier = modifier + 0.5;
219     if (modifier >= 1) modifier -= 1;
220     startPoint = stroke->getPointAtLength(length * modifier);
221     j          = 0.025 + modifier;
222 
223     // draw another animated section
224     for (int i = 0; i < 8; i++) {
225       endPoint = stroke->getPointAtLength(length * j);
226       glVertex2d(startPoint.x, startPoint.y);
227       glVertex2d(endPoint.x, endPoint.y);
228       startPoint = endPoint;
229       j += 0.025;
230       if (j > 1) {
231         j -= 1;
232         startPoint = stroke->getPointAtLength(length * j);
233       }
234     }
235     glEnd();
236   }
237 
238   glLineWidth(1.0f);
239   glPopMatrix();
240 }
241 
242 //=============================================================================
243 
244 /*TPixel TransparencyCheckBlackBgInk = TPixel(255,255,255);
245 TPixel TransparencyCheckWhiteBgInk = TPixel(0,0,0);
246 TPixel TransparencyCheckPaint = TPixel(127,127,127);*/
247 static int Index = 0;
tglDraw(const TVectorRenderData & rd,TRegion * r,bool pushAttribs)248 void tglDraw(const TVectorRenderData &rd, TRegion *r, bool pushAttribs) {
249   checkErrorsByGL;
250   assert(r);
251   checkErrorsByGL;
252   if (!r) return;
253   bool alphaChannel = rd.m_alphaChannel;
254   checkErrorsByGL;
255 
256   int j          = 0;
257   bool visible   = false;
258   int colorCount = 0;
259 
260   TColorStyleP style;
261   if (rd.m_paintCheckEnabled && r->getStyle() == rd.m_colorCheckIndex) {
262     static TSolidColorStyle *redColor = new TSolidColorStyle();
263     redColor->addRef();
264     redColor->setMainColor(TPixel::Red);
265     style = redColor;
266   } else if (rd.m_tcheckEnabled) {
267     static TSolidColorStyle *color = new TSolidColorStyle();
268     color->addRef();
269     color->setMainColor(rd.m_tCheckPaint);
270     style = color;
271   } else
272     style = rd.m_palette->getStyle(r->getStyle());
273 
274   colorCount = style->getColorParamCount();
275   if (colorCount == 0) {  // for example texture
276     visible = true;
277   } else {
278     visible = false;
279     for (j = 0; j < colorCount && !visible; j++) {
280       TPixel32 color = style->getColorParamValue(j);
281       if (rd.m_cf) color = (*(rd.m_cf))(color);
282       if (color.m != 0) visible = true;
283     }
284   }
285   if (visible) {
286     TRegionProp *prop = r->getProp(/*rd.m_palette*/);
287     /// questo codice satva dentro tregion::getprop/////
288     int styleId = r->getStyle();
289     if (styleId) {
290       // TColorStyle * style = rd.m_palette->getStyle(styleId);
291       if (!style->isRegionStyle() || style->isEnabled() == false) {
292         prop = 0;
293       } else {
294         // Warning: The same remark of stroke props holds here.
295         if (!prop || style.getPointer() != prop->getColorStyle()) {
296           r->setProp(style->makeRegionProp(r));
297           prop = r->getProp();
298         }
299       }
300     }
301 
302     ////// draw
303     if (prop) {
304       if (pushAttribs) glPushAttrib(GL_ALL_ATTRIB_BITS);
305 
306       tglEnableLineSmooth(true);
307 //#define DRAW_EDGE_NUMBERS
308 #ifdef DRAW_EDGE_NUMBERS
309       glPushMatrix();
310       tglMultMatrix(rd.m_aff);
311       switch (Index % 7) {
312       case 0:
313         tglColor(TPixel::Red);
314         break;
315       case 1:
316         tglColor(TPixel::Green);
317         break;
318       case 2:
319         tglColor(TPixel::Blue);
320         break;
321       case 3:
322         tglColor(TPixel::Cyan);
323         break;
324       case 4:
325         tglColor(TPixel::Magenta);
326         break;
327       case 5:
328         tglColor(TPixel::Yellow);
329         break;
330       case 6:
331         tglColor(TPixel::Black);
332         break;
333       default:
334         tglColor(TPixel::Red);
335         break;
336       }
337 
338       Index++;
339       if (rIndex == 2) {
340         double y = r->getEdge(0)
341                        ->m_s
342                        ->getThickPoint(
343                            (r->getEdge(0)->m_w0 + r->getEdge(0)->m_w1) / 2.0)
344                        .y;
345         tglDrawSegment(TPointD(-1000, y), TPointD(1000, y));
346       }
347 
348       for (int i = 0; i < (int)r->getEdgeCount(); i++) {
349         TEdge *e  = r->getEdge(i);
350         TPointD p = e->m_s->getPoint(0.8 * e->m_w0 + 0.2 * e->m_w1);
351         if (i == 0)
352           tglDrawText(p,
353                       (QString::number(rIndex) + QString("-0")).toStdString());
354         else
355           tglDrawText(p, QString::number(i).toStdString());
356         if (e->m_index == 3) {
357           tglColor(TPixel::Black);
358           TStroke *s = e->m_s;
359           drawPoint(s->getChunk(0)->getP0(), .3);
360           tglColor(TPixel::Red);
361           tglDrawText(s->getChunk(0)->getP0(),
362                       QString::number(0).toStdString());
363           for (int ii = 0; ii < s->getChunkCount(); ii++) {
364             drawPoint(s->getChunk(ii)->getP2(), .3);
365             if (ii < s->getChunkCount() - 1) {
366               tglColor(TPixel::Red);
367               tglDrawText(s->getChunk(ii)->getP2(),
368                           QString::number(ii + 1).toStdString());
369             }
370           }
371         }
372       }
373       glPopMatrix();
374 #endif
375 
376       if (alphaChannel) {
377         GLboolean red, green, blue, alpha;
378         tglGetColorMask(red, green, blue, alpha);
379 
380         // Draw RGB channels
381         tglEnableBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
382         glColorMask(red, green, blue, GL_FALSE);
383         prop->draw(rd);
384 
385         // Draw Matte channel
386         tglEnableBlending(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
387         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, alpha);
388         prop->draw(rd);
389 
390         glColorMask(red, green, blue, alpha);
391       } else {
392         // pezza: in render, le aree fillate dei custom styles sparivano.
393         if (!rd.m_isOfflineRender || !rd.m_isImagePattern)
394           tglRgbOnlyColorMask();  // RGB components only
395 
396         prop->draw(rd);
397       }
398 
399       if (pushAttribs) glPopAttrib();
400     }
401   }
402 
403   for (UINT i = 0; i < r->getSubregionCount(); i++)
404     tglDraw(rd, r->getSubregion(i), pushAttribs);
405   checkErrorsByGL;
406 }
407 
408 //-----------------------------------------------------------------------------
409 
tglDrawMask(const TVectorRenderData & rd1,const TVectorImage * vim)410 void tglDrawMask(const TVectorRenderData &rd1, const TVectorImage *vim) {
411   UINT i;
412   assert(vim);
413   if (!vim) return;
414   TVectorRenderData rd(rd1);
415 
416   glPushAttrib(GL_ALL_ATTRIB_BITS);
417 
418   if (!rd.m_palette) {
419     TPalette *vPalette = vim->getPalette();
420     assert(vPalette);
421     rd.m_palette = vPalette;
422   }
423   for (i = 0; i < vim->getRegionCount(); i++)
424     tglDraw(rd, vim->getRegion(i), false);
425 
426   glPopAttrib();
427 }
428 
429 //-----------------------------------------------------------------------------
430 
431 namespace {
isOThick(const TStroke * s)432 bool isOThick(const TStroke *s) {
433   int i;
434   for (i = 0; i < s->getControlPointCount(); i++)
435     if (s->getControlPoint(i).thick != 0) return false;
436   return true;
437 }
438 }  // namespace
439 
tglDraw(const TVectorRenderData & rd,const TStroke * s,bool pushAttribs)440 void tglDraw(const TVectorRenderData &rd, const TStroke *s, bool pushAttribs) {
441   assert(s);
442   if (!s) return;
443 
444   TStrokeProp *prop  = 0;
445   bool pushedAttribs = false;
446 
447   try {
448     TColorStyleP style;
449     TStroke *stroke = const_cast<TStroke *>(s);
450     if (rd.m_inkCheckEnabled && s->getStyle() == rd.m_colorCheckIndex) {
451       static TSolidColorStyle *redColor = new TSolidColorStyle();
452       redColor->addRef();
453       redColor->setMainColor(TPixel::Red);
454       style = redColor;
455     } else if (rd.m_ink1CheckEnabled && s->getStyle() == 1) {
456       // Ink #1 Check.
457       // Could possibly merge with above.
458       static TSolidColorStyle *redColor = new TSolidColorStyle();
459       redColor->addRef();
460       redColor->setMainColor(TPixel::Red);
461       style = redColor;
462     } else if (rd.m_tcheckEnabled) {
463       static TSolidColorStyle *color = new TSolidColorStyle();
464       color->addRef();
465       color->setMainColor(rd.m_tCheckInk);
466       style = color;
467     } else
468       style = rd.m_palette->getStyle(stroke->getStyle());
469 
470     if (!rd.m_show0ThickStrokes && isOThick(s) &&
471         dynamic_cast<TSolidColorStyle *>(
472             style.getPointer())  // This is probably to exclude
473                                  // TCenterlineStrokeStyle-like styles
474         && !rd.m_tcheckEnabled)  // I wonder why this?
475       return;
476 
477     // const TStroke& stroke = *s;  //serve???
478 
479     assert(rd.m_palette);
480 
481     prop = s->getProp(/*rd.m_palette*/);
482     /////questo codice stava dentro tstroke::getprop/////////
483     if (prop) prop->getMutex()->lock();
484 
485     if (!style->isStrokeStyle() || style->isEnabled() == false) {
486       if (prop) prop->getMutex()->unlock();
487 
488       prop = 0;
489     } else {
490       // Warning: the following pointers check is conceptually wrong - we
491       // keep it because the props maintain SMART POINTER-like reference to
492       // the associated style. This prevents the style from being destroyed
493       // while still referenced by the prop.
494       if (!prop || style.getPointer() != prop->getColorStyle()) {
495         if (prop) prop->getMutex()->unlock();
496 
497         stroke->setProp(style->makeStrokeProp(stroke));
498         prop = stroke->getProp();
499         if (prop) prop->getMutex()->lock();
500       }
501     }
502 
503     //--------- draw ------------
504     if (!prop) return;
505 
506     if (pushAttribs) glPushAttrib(GL_ALL_ATTRIB_BITS), pushedAttribs = true;
507 
508     bool alphaChannel = rd.m_alphaChannel, antialias = rd.m_antiAliasing;
509     TVectorImagePatternStrokeProp *aux =
510         dynamic_cast<TVectorImagePatternStrokeProp *>(prop);
511     if (aux)  // gli image pattern vettoriali tornano in questa funzione....non
512               // facendo il corpo dell'else'si evita di disegnarli due volte!
513       prop->draw(rd);
514     else {
515       if (antialias)
516         tglEnableLineSmooth(true);
517       else
518         tglEnableLineSmooth(false);
519 
520       if (alphaChannel) {
521         GLboolean red, green, blue, alpha;
522         tglGetColorMask(red, green, blue, alpha);
523 
524         // Draw RGB channels
525         tglEnableBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
526         glColorMask(red, green, blue, GL_FALSE);
527         prop->draw(rd);
528 
529         // Draw Matte channel
530         tglEnableBlending(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
531         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, alpha);
532         prop->draw(rd);
533 
534         glColorMask(red, green, blue, alpha);
535       } else {
536         tglEnableBlending(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
537         prop->draw(rd);
538       }
539     }
540 
541     if (pushAttribs) glPopAttrib(), pushedAttribs = false;
542 
543     prop->getMutex()->unlock();
544     //---------------------
545   } catch (...) {
546     if (prop) prop->getMutex()->unlock();
547     if (pushedAttribs) glPopAttrib();
548   }
549 }
550 
551 //------------------------------------------------------------------------------------
552 
tglDoDraw(const TVectorRenderData & rd,TRegion * r)553 static void tglDoDraw(const TVectorRenderData &rd, TRegion *r) {
554   bool visible   = false;
555   int colorCount = 0;
556   if (!r) return;
557 
558   TColorStyleP style = rd.m_palette->getStyle(r->getStyle());
559   colorCount         = style->getColorParamCount();
560   if (colorCount == 0)  // for example texture
561     visible = true;
562   else {
563     visible = false;
564     for (int j = 0; j < colorCount && !visible; j++) {
565       TPixel32 color = style->getColorParamValue(j);
566       if (rd.m_cf) color = (*(rd.m_cf))(color);
567       if (color.m != 0) visible = true;
568     }
569   }
570   if (visible)
571     tglDraw(rd, r, false);
572   else
573     for (UINT j = 0; j < r->getSubregionCount(); j++)
574       tglDraw(rd, r->getSubregion(j), false);
575 }
576 
577 //------------------------------------------------------------------------------------
578 
tglDoDraw(const TVectorRenderData & rd,const TStroke * s)579 static bool tglDoDraw(const TVectorRenderData &rd, const TStroke *s) {
580   bool visible   = false;
581   int colorCount = 0;
582 
583   const TPalette *palette = rd.m_palette;
584 
585   int styleId = s->getStyle();
586   // assert(0<=styleId && styleId<stylesCount);
587   TColorStyleP style = palette->getStyle(styleId);
588   assert(style);
589   colorCount = style->getColorParamCount();
590   if (colorCount == 0)
591     visible = true;
592   else {
593     visible = false;
594     for (int j = 0; j < style->getColorParamCount() && !visible; j++) {
595       TPixel32 color = style->getColorParamValue(j);
596       if (rd.m_cf) color = (*(rd.m_cf))(color);
597       if (color.m != 0) visible = true;
598     }
599   }
600 
601   bool ret = false;
602 
603   if (visible) {
604     // Change stroke color to blue if guided drawing
605     if (rd.m_showGuidedDrawing && rd.m_highLightNow) {
606       TVectorRenderData *newRd = new TVectorRenderData(
607           rd, rd.m_aff, rd.m_clippingRect, rd.m_palette, rd.m_guidedCf);
608       tglDraw(*newRd, s, false);
609       delete newRd;
610       TStroke *new_s = (TStroke *)s;
611       drawFirstControlPoint(rd, new_s);
612       ret = rd.m_animatedGuidedDrawing;
613     } else {
614       tglDraw(rd, s, false);
615     }
616   }
617 #ifdef _DEBUG
618 // drawControlPoints(rd, vim->getStroke(i), sqrt(tglGetPixelSize2()), true);
619 // assert(checkQuadraticDistance(vim->getStroke(i),true));
620 #endif
621   return ret;
622 }
623 
624 //------------------------------------------------------------------------------------
625 
626 namespace {
627 
doDraw(const TVectorImage * vim,const TVectorRenderData & _rd,bool drawEnteredGroup,TStroke ** guidedStroke=0)628 void doDraw(const TVectorImage *vim, const TVectorRenderData &_rd,
629             bool drawEnteredGroup, TStroke **guidedStroke = 0) {
630   static TOnionFader *fade = new TOnionFader(TPixel::White, 0.5);
631 
632   TVectorRenderData rd(_rd);
633 
634   if (!rd.m_palette) {
635     TPalette *vPalette = vim->getPalette();
636     rd.m_palette       = vPalette;
637     if (!vPalette) return;
638   }
639 
640   if (!drawEnteredGroup && !rd.m_isIcon && vim->isInsideGroup() > 0)
641     rd.m_cf = fade;
642 
643   TVectorRenderData rdRegions = rd;
644 
645   /*if (rd.m_drawRegions && rd.m_isImagePattern)//gli image pattern hanno
646 bisogno dell'antialiasig per le linee, ma sulle aree ci sarebbero un sacco di
647 assert
648 rdRegions.m_alphaChannel = rdRegions.m_antiAliasing = false;*/
649   UINT strokeIndex = 0;
650   Index            = 0;
651 
652   while (strokeIndex <
653          vim->getStrokeCount())  // ogni ciclo di while disegna un gruppo
654   {
655     int currStrokeIndex = strokeIndex;
656     if (!rd.m_isIcon && vim->isInsideGroup() > 0 &&
657         ((drawEnteredGroup && !vim->isEnteredGroupStroke(strokeIndex)) ||
658          (!drawEnteredGroup && vim->isEnteredGroupStroke(strokeIndex)))) {
659       while (strokeIndex < vim->getStrokeCount() &&
660              vim->sameGroup(strokeIndex, currStrokeIndex))
661         strokeIndex++;
662       continue;
663     }
664 
665     if (rd.m_drawRegions)
666       for (UINT regionIndex = 0; regionIndex < vim->getRegionCount();
667            regionIndex++)
668         if (vim->sameGroupStrokeAndRegion(currStrokeIndex, regionIndex))
669           tglDoDraw(rdRegions, vim->getRegion(regionIndex));
670     while (strokeIndex < vim->getStrokeCount() &&
671            vim->sameGroup(strokeIndex, currStrokeIndex)) {
672       if (rd.m_indexToHighlight != strokeIndex) {
673         rd.m_highLightNow = false;
674       } else {
675         rd.m_highLightNow = true;
676       }
677 #if DISEGNO_OUTLINE == 1
678       CurrStrokeIndex = strokeIndex;
679       CurrVimg        = vim;
680 #endif
681       bool isGuided = tglDoDraw(rd, vim->getStroke(strokeIndex));
682       if (isGuided && guidedStroke) *guidedStroke = vim->getStroke(strokeIndex);
683       strokeIndex++;
684     }
685   }
686 }
687 }  // namespace
688 
689 //------------------------------------------------------------------------------------
690 
tglDraw(const TVectorRenderData & rd,const TVectorImage * vim,TStroke ** guidedStroke)691 void tglDraw(const TVectorRenderData &rd, const TVectorImage *vim,
692              TStroke **guidedStroke) {
693   assert(vim);
694   if (!vim) return;
695 
696   QMutexLocker sl(vim->getMutex());
697 
698   checkErrorsByGL;
699   checkErrorsByGL;
700 
701   glPushAttrib(GL_ALL_ATTRIB_BITS);
702 
703   // if(!rd.m_palette) rd.m_palette = vim->getPalette();
704   // mylog("tglDraw start; mutex=" + toString((unsigned long)&vim->getMutex()));
705 
706   glEnable(GL_ALPHA_TEST);
707   glAlphaFunc(GL_GREATER, 0);
708 
709   doDraw(vim, rd, false, guidedStroke);
710   if (!rd.m_isIcon && vim->isInsideGroup() > 0)
711     doDraw(vim, rd, true, guidedStroke);
712 
713   glDisable(GL_ALPHA_TEST);
714 
715   glPopAttrib();
716 
717 #ifdef _DEBUG
718   vim->drawAutocloses(rd);
719 #endif
720   checkErrorsByGL;
721   // mylog("tglDraw stop");
722 }
723 
724 //-----------------------------------------------------------------------------
725 //-----------------------------------------------------------------------------
726