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