PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
sdl/PlatformDrawObject.cpp
Go to the documentation of this file.
1//* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
3// Name: src/platforms/sdl/PlatformDrawObject.cpp
4// Purpose: Platform-specific classes drawing things.
5// Author: Shane T. Mueller, Ph.D.
6// Copyright: (c) 2005-2026 Shane T. Mueller <smueller@obereed.net>
7// License: GPL 2
8//
9//
10//
11// This file is part of the PEBL project.
12//
13// PEBL is free software; you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation; either version 2 of the License, or
16// (at your option) any later version.
17//
18// PEBL is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with PEBL; if not, write to the Free Software
25// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
28#include "PlatformDrawObject.h"
29#include "PlatformWidget.h"
30
31#ifdef PEBL_OSX
32#include "SDL.h"
33#include "SDL2_gfxPrimitives.h"
34#else
35#include "SDL.h"
36#include "SDL2_gfxPrimitives.h"
37#endif
38
39
40
41#include "../../base/PList.h"
42#include "../../base/Variant.h"
43#include "../../base/PComplexData.h"
44
45#include <iostream>
46#include <list>
47//using std::list;
48using std::vector;
49// cout removed - use cerr for debug output
50using std::endl;
51// PlatformDrawObject::PlatformDrawObject(PlatformWidget * widget)
52// {
53// mSurface = widget->GetSDL_Surface();
54// mParentSurface = NULL;
55// mIsVisible=true;
56// }
57
58// PlatformDrawObject::PlatformDrawObject(PlatformWidget * widget, int x, int y ):
59// mSurface(widget->GetSDL_Surface())
60// {
61
62// mX = x;
63// mY = y;
64
65
66// }
67
68// PlatformDrawObject::~PlatformDrawObject()
69// {
70// //Don't delete the surface--it belongs to somebody else.
71// }
72
73// bool PlatformDrawObject::Draw()
74// {
75
76// return true;
77// }
78
79
80// std::ostream & PlatformDrawObject::SendToStream(std::ostream& out) const
81// {
82
83// out << "A draw object";
84// return out;
85// }
86
87
88// SDL_Surface * PlatformDrawObject::GetSDL_Surface()
89// {
90// return mSurface;
91// }
92
93// bool PlatformDrawObject::SetParentSurface(SDL_Surface * surface)
94// {
95// mParentSurface = surface;
96// return true;
97// }
98
99
100// ///This needs to be used on some platforms/video cards
101// bool PlatformDrawObject::LockSurface()
102// {
103// if(SDL_MUSTLOCK(mSurface))
104// {
105
106// //cout << "Locking-------->" << endl;
107// //The below returns 0 on success, -1 otherwise,
108// //so reverse it for t/f
109// if(SDL_LockSurface(mSurface)<0)
110// {
111// std::cerr << "Need to lock surface but can't\n";
112// return false;
113// }
114// return true;
115// }
116
117// return false;
118
119// }
120
121// ///This needs to be used on some platforms/video cards
122// bool PlatformDrawObject::UnlockSurface()
123// {
124// if(SDL_MUSTLOCK(mSurface))
125// {
126// // cout << "------->Unlocking" << endl;
127// SDL_UnlockSurface(mSurface);
128// }
129// return true;
130// }
131
132
133
134
135PlatformLine::PlatformLine(int x1, int y1, int dx, int dy, Variant fg):
136 PLine(x1,y1,dx,dy,fg)
137
138{
139 mNeedsTexture=false;
141
142 mSurface =NULL;
143 mParent = NULL;
144 mIsVisible=true;
145}
146
151
152std::ostream & PlatformLine::SendToStream(std::ostream& out) const
153{
154 out << "<A line:"<< mX << ", " << mY << "| w: " << mDX+mX << ", h:" << mDY+mY << std::endl;
155 return out;
156}
157
159{
160
161
162 int result=0;
163
164 if(mParent && mRenderer)
165 {
166
167 //startX,startX represent the 'pigrvot' point on which
168 //you'd want to pin the surface to the parent surface.
169
170
171
172
173 SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
174 if(mAntiAliased)
175 {
176
177 result = aalineRGBA(mRenderer,mX,mY,mX+mDX,mY+mDY,
178 GetColor()->GetRed(), GetColor()->GetGreen(),
179 GetColor()->GetBlue(), GetColor()->GetAlpha());
180
181 }
182 else
183 {
184 result = lineRGBA(mRenderer,mX,mY,mX+mDX,mY+mDY,
185 GetColor()->GetRed(), GetColor()->GetGreen(),
186 GetColor()->GetBlue(), GetColor()->GetAlpha());
187 }
188 SDL_SetRenderTarget(mRenderer,NULL);
189 }
190 return result;
191}
192
193
194
195PlatformThickLine::PlatformThickLine(int x1, int y1, int x2, int y2,
196 int thickness, Variant fg):
197 PThickLine(x1,y1,x2,y2,thickness,fg)
198{
199
200 mNeedsTexture=false;
202
203 mSurface =NULL;
204 mParent = NULL;
205 mIsVisible=true;
206}
207
211
212std::ostream & PlatformThickLine::SendToStream(std::ostream& out) const
213{
214 out << "<A thick line:"<< mX1 << ", " << mY1 << "| w: " << mX2 << ", h:" << mY2 << std::endl;
215 return out;
216}
217
219{
220
221 //First, create a sdl_surface with blank background to draw on:
222 int result=0;
223
224 if(mParent && mRenderer)
225 {
226
227 SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
228
229 result = thickLineRGBA(mRenderer,mX1,mY1,mX2,mY2,mThickness,
230 GetColor()->GetRed(), GetColor()->GetGreen(),
231 GetColor()->GetBlue(), GetColor()->GetAlpha());
232 SDL_SetRenderTarget(mRenderer,NULL);
233 }
234 return result;
235}
236
237
238
239PlatformRectangle::PlatformRectangle(int x1, int y1, int dx, int dy, Variant fg, bool filled):
240 PRectangle(x1,y1,dx,dy,fg,filled)
241
242
243{
244 mNeedsTexture=false;
246 mSurface =NULL;
248 mIsVisible=true;
249}
250
254
256{
257
258 int result = -1;
259 if(mParent && mRenderer)
260 {
261 SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
262
263 if(mFilled)
264 {
265 result = boxRGBA(mRenderer,mX - mDX/2, mY - mDY/2, mX+mDX/2, mY+mDY/2,
266 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
267 }
268 else
269 {
270 result = rectangleRGBA(mRenderer,mX - mDX/2, mY - mDY/2, mX+mDX/2, mY+mDY/2,
271 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
272 }
273 SDL_SetRenderTarget(mRenderer,NULL);
274 }
275 return result;
276
277}
278
279std::ostream & PlatformRectangle::SendToStream(std::ostream& out) const
280{
281 out << "A Rectangle"<< mX << " " << mY << " " << mDX << " " << mDY << std::endl;
282 return out;
283}
284
285
286PlatformSquare::PlatformSquare(int x, int y, int size, Variant fg, bool filled):
287 PSquare(x,y,size,fg,filled)
288
289
290{
291 mSurface =NULL;
292 mNeedsTexture=false;
294 mParent = NULL;
295 mIsVisible=true;
296}
297
301
302
304
305{
306
307
308 int result=-1;
309 if(mParent && mRenderer)
310 {
311
312 SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
313
314 if(mFilled)
315 {
316 result = boxRGBA(mRenderer,mX - mDX/2, mY - mDY/2, mX+mDX/2, mY+mDY/2,
317 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
318 }
319 else
320 {
321 result = rectangleRGBA(mRenderer,mX - mDX/2, mY - mDY/2, mX+mDX/2, mY+mDY/2,
322 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
323 }
324 SDL_SetRenderTarget(mRenderer,NULL);
325 }
326
327 return result;
328}
329
330
331std::ostream & PlatformSquare::SendToStream(std::ostream& out) const
332{
333 out << "A Square:"<< mX << " " << mY << " " << mDX << " " << mDY << " vis: "<<mIsVisible << std::endl;
334 return out;
335}
336
337
338
339
340PlatformEllipse::PlatformEllipse(int x1, int y1, int dx, int dy, Variant fg, bool filled):
341 PEllipse(x1,y1,dx,dy,fg, filled)
342
343{
344 mNeedsTexture=false;
346 mSurface =NULL;
347 mParent = NULL;
348
349 mIsVisible=true;
350
351// mIsVisible=true;
352// mX = x1;
353// mY = y1;
354
355}
356
361
362std::ostream & PlatformEllipse::SendToStream(std::ostream& out) const
363{
364 out << "<An ellipse:"<< mX << ", " << mY << ":" << mRX << ", " << mRY << std::endl;
365 return out;
366}
367
369{
370
371 int result=-1;
372 if(mParent && mRenderer)
373 {
374 SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
375
376 //LockSurface();
377 if(mFilled)
378 {
379
380 //aa ellipse only handles unfilled, so we need to draw it on-top.
381 if(mAntiAliased)
382 {
383 result = aaellipseRGBA(mRenderer,mX, mY, mRX, mRY,
384 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
385 }
386
387
388 result = filledEllipseRGBA(mRenderer,mX, mY, mRX, mRY,
389 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
390 }
391 else
392 {
393 if(mAntiAliased)
394 {
395 result = aaellipseRGBA(mRenderer,mX, mY, mRX, mRY,
396 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
397 }else
398 {
399 result = ellipseRGBA(mRenderer,mX, mY, mRX, mRY,
400 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
401 }
402 }
403 SDL_SetRenderTarget(mRenderer,NULL);
404 }
405 //UnlockSurface();
406 return result;
407}
408
409
410
411PlatformCircle::PlatformCircle(int x1, int y1, int r, Variant fg, bool filled):
412 PCircle(x1,y1,r,fg,filled)
413{
414
415 mNeedsTexture=false;
417 mSurface =NULL;
418 mParent = NULL;
419 mIsVisible=true;
420
421
422}
423
428
429std::ostream & PlatformCircle::SendToStream(std::ostream& out) const
430{
431 out << "<A Circle :"<< mX << ", " << mY << ":" << mR << std::endl;
432 return out;
433}
434
436{
437 int result=-1;
438 //LockSurface();
439 if(mParent && mRenderer)
440 {
441 SDL_SetRenderTarget(mRenderer,
442 dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
443
444 if(mFilled)
445 {
446
447 if(mAntiAliased)
448 {
449 int result2 = aacircleRGBA(mRenderer, mX, mY, (int)mR,
450 GetColor()->GetRed(),
451 GetColor()->GetGreen(),
452 GetColor()->GetBlue(),
453 GetColor()->GetAlpha());
454 if(result2<0)
455 {
456 PError::SignalFatalError("Failed to render aa circle component.");
457 }
458 }
459
460
461 result = filledCircleRGBA(mRenderer, mX, mY, (int)mR,
462 GetColor()->GetRed(),
463 GetColor()->GetGreen(),
464 GetColor()->GetBlue(),
465 GetColor()->GetAlpha());
466 }
467 else
468 {
469
470 if(mAntiAliased)
471 {
472
473 result = aacircleRGBA(mRenderer, mX, mY, (int)mR,
474 GetColor()->GetRed(),
475 GetColor()->GetGreen(),
476 GetColor()->GetBlue(),
477 GetColor()->GetAlpha());
478 }
479 else
480 {
481
482 result = circleRGBA(mRenderer,mX, mY, (int)mR,
483 GetColor()->GetRed(),
484 GetColor()->GetGreen(),
485 GetColor()->GetBlue(),
486 GetColor()->GetAlpha());
487
488 }
489 }
490 SDL_SetRenderTarget(mRenderer,NULL);
491 }
492 //UnlockSurface();
493 return result;
494}
495
496
497
498
499PlatformPolygon::PlatformPolygon(int x1, int y1, Variant xpoints, Variant ypoints, Variant fg, bool filled):
500 PPolygon(x1,y1,xpoints,ypoints,fg,filled)
501
502{
503 mNeedsTexture=false;
505 mSurface =NULL;
506 mParent = NULL;
507 mIsVisible=true;
508
509}
510
515
516std::ostream & PlatformPolygon::SendToStream(std::ostream& out) const
517{
518 out << "<A Polygon :"<< mX << ", " << mY << ":" << std::endl;
519 return out;
520}
521
523{
524 int result = -1;
525 if(mParent && mRenderer)
526 {
527
528 result = SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
529
530 if(result < 0)
531 {
532
533 std::cerr << " SetRenderTarget failed in PlatformPolygon with error code: " << result << endl;
534 cerr << "SDL message: " << SDL_GetError() << endl;
535 cerr << *this << endl;
536
537 }
538
539
540 //We need to transform the double-list points into int vectors for
541 //the x and y points, plus the length.
542
543 PList * pxlist = mXPoints.GetComplexData()->GetList();
544 PList * pylist = mYPoints.GetComplexData()->GetList();
545
546 unsigned long int length = pxlist->Length();
547 Sint16 *x = new Sint16[length];
548 Sint16 *y = new Sint16[length];
549
550 vector<Variant>::iterator p1 = pxlist->Begin();
551 vector<Variant>::iterator p2 = pylist->Begin();
552
553 int i = 0;
554 while(p1 != pxlist->End())
555 {
556 x[i]= (Sint16)((int)(*p1)) + (Sint16)mX;
557 y[i]= (Sint16)((int)(*p2)) + (Sint16)mY;
558 p1++;
559 p2++;
560 i++;
561 }
562
563
564 if(mFilled)
565 {
566
567 if(mAntiAliased)
568 {
569 result = aapolygonRGBA(mRenderer,x,y,(int)length,
570 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
571
572
573
574 if(result < 0)
575 {
576
577 std::cerr << " rendering aapolygonRGBA failed in PlatformPolygon with error code: " << result << endl;
578 cerr << "SDL message: " << SDL_GetError() << endl;
579 cerr << *this << endl;
580
581
582 }
583
584
585 }
586 result = filledPolygonRGBA(mRenderer,x,y,(int)length,
587 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
588
589 if(result < 0)
590 {
591
592 std::cerr << " rendering filledPolygonRGBA failed in PlatformPolygon with error code: " << result << endl;
593 cerr << "SDL message: " << SDL_GetError() << endl;
594 cerr << *this << endl;
595
596
597 }
598
599 }
600 else
601 {
602 if(mAntiAliased)
603 {
604 result = aapolygonRGBA(mRenderer,x,y,(int)length,
605 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
606 }else
607 {
608 result =polygonRGBA(mRenderer,x,y,(int)length,
609 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
610 }
611 if(result < 0)
612 {
613
614 std::cerr << " rendering polygonRGBA failed in PlatformPolygon with error code: " << result << endl;
615 cerr << "SDL message: " << SDL_GetError() << endl;
616 cerr << *this << endl;
617
618
619 }
620
621 }
622 delete[] x;
623 delete[] y;
624 result = SDL_SetRenderTarget(mRenderer,NULL);
625
626 if(result < 0)
627 {
628
629 std::cerr << " Resetting rendertarget failed in PlatformPolygon with error code: " << result << endl;
630 cerr << "SDL message: " << SDL_GetError() << endl;
631 cerr << *this << endl;
632
633
634 }
635
636
637 }
638 //UnlockSurface();
639 return result;
640}
641
642
643
644PlatformBezier::PlatformBezier(int x1, int y1, Variant xpoints, Variant ypoints, int steps, Variant fg):
645 PBezier(x1,y1,xpoints,ypoints,steps, fg)
646{
647 mNeedsTexture=false;
649 mSurface =NULL;
650 mParent = NULL;
651 mIsVisible=true;
652
653}
654
659
660std::ostream & PlatformBezier::SendToStream(std::ostream& out) const
661{
662 out << "<A Bezier :"<< mX << ", " << mY << ":" << std::endl;
663 return out;
664}
665
667{
668 int result=-1;
669
670 if(mParent && mRenderer)
671 {
672 SDL_SetRenderTarget(mRenderer, dynamic_cast<PlatformWidget*>(mParent)->GetSDL_Texture());
673
674 //We need to transform the double-list points into int vectors for
675 //the x and y points, plus the length.
676
677 PList * pxlist = mXPoints.GetComplexData()->GetList();
678 PList * pylist = mYPoints.GetComplexData()->GetList();
679 unsigned long int length = pxlist->Length();
680 Sint16 *x = new Sint16[length];
681 Sint16 *y = new Sint16[length];
682
683 vector<Variant>::iterator p1 = pxlist->Begin();
684 vector<Variant>::iterator p2 = pylist->Begin();
685
686 int i = 0;
687 while(p1 != pxlist->End())
688 {
689 x[i]= (Sint16)((int)(*p1)) + (Sint16)mX;
690 y[i]= (Sint16)((int)(*p2)) + (Sint16)mY;
691 p1++;
692 p2++;
693 i++;
694
695 }
696
697
698 result = bezierRGBA(mRenderer,x,y,(int)length,(int)mSteps,
699 GetColor()->GetRed(), GetColor()->GetGreen(), GetColor()->GetBlue(), GetColor()->GetAlpha());
700
701 delete[] x;
702 delete[] y;
703
704 SDL_SetRenderTarget(mRenderer,NULL);
705 }
706
707 return result;
708}
#define NULL
Definition BinReloc.cpp:317
@ CDT_THICKLINE
Definition PEBLObject.h:61
@ CDT_DRAWOBJECT
Definition PEBLObject.h:60
Variant mYPoints
pInt mSteps
Variant mXPoints
pDouble mR
PList * GetList() const
bool mAntiAliased
Definition PDrawObject.h:69
PColor * GetColor() const
ComplexDataType mCDT
Definition PEBLObject.h:109
pInt mDX
Definition PDrawObject.h:96
pInt mDY
Definition PDrawObject.h:97
Definition PList.h:45
std::vector< Variant >::const_iterator End() const
Definition PList.cpp:132
std::vector< Variant >::const_iterator Begin() const
Definition PList.cpp:127
unsigned long Length() const
Definition PList.h:89
Variant mYPoints
Variant mXPoints
pInt mThickness
pInt mX
Definition PWidget.h:125
pInt mY
Definition PWidget.h:125
PWidget * mParent
Definition PWidget.h:154
bool mIsVisible
Definition PWidget.h:150
virtual bool Draw()
This method initiates everything needed to display the main window
PlatformBezier(int x, int y, Variant xpoints, Variant ypoints, int steps, Variant fg)
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
PlatformCircle(int x1, int y1, int r, Variant fg, bool filled)
virtual bool Draw()
This method initiates everything needed to display the main window
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
virtual bool Draw()
This method initiates everything needed to display the main window
PlatformEllipse(int x1, int y1, int dx, int dy, Variant fg, bool filled)
virtual bool Draw()
This method initiates everything needed to display the main window
PlatformLine(int x1, int y1, int dx, int dy, Variant fg)
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
PlatformPolygon(int x, int y, Variant xpoints, Variant ypoints, Variant fg, bool filled)
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
virtual bool Draw()
This method initiates everything needed to display the main window
virtual bool Draw()
This method initiates everything needed to display the main window
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
PlatformRectangle(int x1, int y1, int dx, int dy, Variant fg, bool filled)
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
PlatformSquare(int x, int y, int size, Variant fg, bool filled)
virtual bool Draw()
This method initiates everything needed to display the main window
virtual std::ostream & SendToStream(std::ostream &out) const
An inheritable printing class used by PEBLObjectBase::operator<<.
PlatformThickLine(int x1, int y1, int x2, int y2, int width, Variant fg)
virtual bool Draw()
This method initiates everything needed to display the main window
SDL_Surface * mSurface
SDL_Renderer * mRenderer
virtual SDL_Texture * GetSDL_Texture()
Used to extract an SDL surface from the widget. Used by children drawing themselves on their parent.
PComplexData * GetComplexData() const
Definition Variant.cpp:1299
void SignalFatalError(const std::string &message)