rays 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/.doc/ext/rays/bitmap.cpp +76 -53
  2. data/.doc/ext/rays/font.cpp +31 -27
  3. data/.doc/ext/rays/image.cpp +44 -37
  4. data/.doc/ext/rays/native.cpp +6 -0
  5. data/.doc/ext/rays/painter.cpp +276 -160
  6. data/.doc/ext/rays/rays.cpp +8 -9
  7. data/.doc/ext/rays/texture.cpp +50 -28
  8. data/.gitignore +14 -0
  9. data/Rakefile +5 -30
  10. data/VERSION +1 -1
  11. data/ext/rays/bitmap.cpp +77 -53
  12. data/ext/rays/bounds.cpp +426 -0
  13. data/ext/rays/color.cpp +199 -0
  14. data/ext/rays/defs.h +1 -18
  15. data/ext/rays/extconf.rb +10 -8
  16. data/ext/rays/font.cpp +31 -27
  17. data/ext/rays/image.cpp +44 -37
  18. data/ext/rays/matrix.cpp +154 -0
  19. data/ext/rays/native.cpp +6 -0
  20. data/ext/rays/painter.cpp +288 -163
  21. data/ext/rays/point.cpp +175 -0
  22. data/ext/rays/rays.cpp +8 -9
  23. data/ext/rays/texture.cpp +52 -28
  24. data/include/rays.h +1 -2
  25. data/include/rays/bitmap.h +5 -3
  26. data/include/rays/bounds.h +94 -0
  27. data/include/rays/color.h +53 -0
  28. data/include/rays/colorspace.h +2 -2
  29. data/include/rays/exception.h +1 -1
  30. data/include/rays/font.h +7 -3
  31. data/include/rays/image.h +6 -2
  32. data/include/rays/matrix.h +63 -0
  33. data/include/rays/opengl.h +1 -1
  34. data/include/rays/painter.h +138 -39
  35. data/include/rays/point.h +39 -0
  36. data/include/rays/ruby.h +3 -0
  37. data/include/rays/ruby/bitmap.h +5 -3
  38. data/include/rays/ruby/bounds.h +41 -0
  39. data/include/rays/ruby/color.h +41 -0
  40. data/include/rays/ruby/font.h +5 -3
  41. data/include/rays/ruby/image.h +5 -3
  42. data/include/rays/ruby/matrix.h +41 -0
  43. data/include/rays/ruby/painter.h +5 -3
  44. data/include/rays/ruby/point.h +41 -0
  45. data/include/rays/ruby/texture.h +5 -3
  46. data/include/rays/texture.h +6 -2
  47. data/lib/rays.rb +3 -0
  48. data/lib/rays/autoinit.rb +1 -1
  49. data/lib/rays/bitmap.rb +15 -1
  50. data/lib/rays/bounds.rb +138 -0
  51. data/lib/rays/color.rb +52 -0
  52. data/lib/rays/ext.rb +4 -0
  53. data/lib/rays/image.rb +1 -1
  54. data/lib/rays/module.rb +9 -2
  55. data/lib/rays/painter.rb +40 -41
  56. data/lib/rays/point.rb +82 -0
  57. data/lib/rays/texture.rb +1 -1
  58. data/rays.gemspec +16 -37
  59. data/src/bounds.cpp +234 -0
  60. data/src/cocoa/bitmap.mm +4 -4
  61. data/src/cocoa/font.mm +35 -30
  62. data/src/cocoa/rays.mm +2 -0
  63. data/src/color.cpp +77 -0
  64. data/src/colorspace.cpp +3 -3
  65. data/src/exception.cpp +3 -18
  66. data/src/image.cpp +9 -2
  67. data/src/matrix.cpp +103 -0
  68. data/src/painter.cpp +475 -224
  69. data/src/point.cpp +52 -0
  70. data/src/texture.cpp +14 -2
  71. data/src/win32/bitmap.cpp +2 -2
  72. data/src/win32/gdi.cpp +22 -13
  73. data/src/win32/gdi.h +7 -7
  74. data/test/helpers.rb +1 -5
  75. data/test/test_bitmap.rb +9 -0
  76. data/test/test_bounds.rb +246 -0
  77. data/test/test_color.rb +88 -0
  78. data/test/test_font.rb +28 -0
  79. data/test/test_image.rb +9 -0
  80. data/test/test_painter.rb +1 -3
  81. data/test/test_point.rb +121 -0
  82. data/test/test_rays.rb +2 -3
  83. data/test/test_texture.rb +1 -3
  84. metadata +146 -75
  85. data/include/rays/helpers.h +0 -37
  86. data/include/rays/transform.h +0 -35
  87. data/src/helpers.cpp +0 -22
  88. data/src/transform.cpp +0 -88
data/src/cocoa/bitmap.mm CHANGED
@@ -204,7 +204,7 @@ namespace Rays
204
204
  const void*
205
205
  Bitmap::data () const
206
206
  {
207
- return const_cast<Bitmap*>(this)->data();
207
+ return const_cast<This*>(this)->data();
208
208
  }
209
209
 
210
210
  Bitmap::operator bool () const
@@ -233,10 +233,10 @@ namespace Rays
233
233
  CGImageRef image = [imagerep CGImage];
234
234
  if (!image) return false;
235
235
 
236
- int width = CGImageGetWidth(image);
237
- int height = CGImageGetHeight(image);
236
+ size_t width = CGImageGetWidth(image);
237
+ size_t height = CGImageGetHeight(image);
238
238
 
239
- *bmp = Bitmap(width, height, ColorSpace(RGBA, true));
239
+ *bmp = Bitmap((int) width, (int) height, ColorSpace(RGBA, true));
240
240
  if (!*bmp) return false;
241
241
 
242
242
  CGContextRef context = bmp->self->get_context();
data/src/cocoa/font.mm CHANGED
@@ -102,35 +102,39 @@ namespace Rays
102
102
  }
103
103
 
104
104
  bool
105
- Font::get_extent (coord* width, coord* height, const char* str) const
105
+ Font::get_width (coord* width, const char* str) const
106
106
  {
107
- if (!*this) return false;
107
+ if (!width || !str || !*this) return false;
108
108
 
109
- if (width) *width = 0;
110
- if (height) *height = 0;
111
-
112
- CGFloat ascent = 0, descent = 0, leading = 0;
113
- if (width)
109
+ if (*str == '\0')
114
110
  {
115
- CTLineRef line = make_line(self->font, str);
116
- if (!line) return false;
117
-
118
- *width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
119
- CFRelease(line);
111
+ *width = 0;
112
+ return true;
120
113
  }
121
114
 
122
- if (height)
123
- {
124
- if (width)
125
- *height = ascent + descent + leading;
126
- else
127
- {
128
- *height =
129
- CTFontGetAscent(self->font) +
130
- CTFontGetDescent(self->font) +
131
- CTFontGetLeading(self->font);
132
- }
133
- }
115
+ CTLineRef line = make_line(self->font, str);
116
+ if (!line) return false;
117
+
118
+ *width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
119
+ CFRelease(line);
120
+
121
+ return true;
122
+ }
123
+
124
+ bool
125
+ Font::get_height (
126
+ coord* height, coord* ascent, coord* descent, coord* leading) const
127
+ {
128
+ if ((!height && !ascent && !descent && !leading) || !*this) return false;
129
+
130
+ CGFloat asc = CTFontGetAscent(self->font);
131
+ CGFloat desc = CTFontGetDescent(self->font);
132
+ CGFloat lead = CTFontGetLeading(self->font);
133
+
134
+ if (height) *height = asc + desc + lead;
135
+ if (ascent) *ascent = asc;
136
+ if (descent) *descent = desc;
137
+ if (leading) *leading = lead;
134
138
 
135
139
  return true;
136
140
  }
@@ -167,12 +171,14 @@ namespace Rays
167
171
  CTLineRef line = make_line(font.self->font, str);
168
172
  if (!line) return false;
169
173
 
170
- coord width = 0, height = 0;
171
- if (!font.get_extent(&width, &height, str))
174
+ coord width = 0, height = 0, ascent = 0;
175
+ if (!font.get_width(&width, str) || !font.get_height(&height, &ascent))
172
176
  return false;
173
177
 
174
- CGRect rect = CGRectMake(
175
- x, context_height - height - y, width, height);
178
+ height = ceil(height);
179
+ ascent = floor(ascent);
180
+
181
+ CGRect rect = CGRectMake(x, context_height - height - y, width, height);
176
182
  CGContextClearRect(context, rect);
177
183
  //CGContextSetRGBFillColor(context, 0, 0, 0, 1);
178
184
  //CGContextFillRect(context, rect);
@@ -180,8 +186,7 @@ namespace Rays
180
186
 
181
187
  CGContextSaveGState(context);
182
188
  CGContextSetTextMatrix(context, CGAffineTransformIdentity);
183
- CGContextSetTextPosition(
184
- context, x, context_height - CTFontGetAscent(font.self->font) - y);
189
+ CGContextSetTextPosition(context, x, context_height - ascent - y);
185
190
  CTLineDraw(line, context);
186
191
  CGContextRestoreGState(context);
187
192
 
data/src/cocoa/rays.mm CHANGED
@@ -23,6 +23,7 @@ namespace Rays
23
23
  init ()
24
24
  {
25
25
  if (global::pool) return false;
26
+
26
27
  global::pool = [[NSAutoreleasePool alloc] init];
27
28
  return true;
28
29
  }
@@ -31,6 +32,7 @@ namespace Rays
31
32
  fin ()
32
33
  {
33
34
  if (!global::pool) return false;
35
+
34
36
  [global::pool release];
35
37
  global::pool = nil;
36
38
  return true;
data/src/color.cpp ADDED
@@ -0,0 +1,77 @@
1
+ #include "rays/color.h"
2
+
3
+
4
+ namespace Rays
5
+ {
6
+
7
+
8
+ Color::Color (float value, float alpha)
9
+ {
10
+ set(value, alpha);
11
+ }
12
+
13
+ Color::Color (float red, float green, float blue, float alpha)
14
+ {
15
+ set(red, green, blue, alpha);
16
+ }
17
+
18
+ Color
19
+ Color::dup () const
20
+ {
21
+ return *this;
22
+ }
23
+
24
+ Color&
25
+ Color::set (float value, float alpha)
26
+ {
27
+ return set(value, value, value, alpha);
28
+ }
29
+
30
+ Color&
31
+ Color::set (float red, float green, float blue, float alpha)
32
+ {
33
+ this->red = red;
34
+ this->green = green;
35
+ this->blue = blue;
36
+ this->alpha = alpha;
37
+ return *this;
38
+ }
39
+
40
+ bool
41
+ Color::get (float* red, float* green, float* blue, float* alpha) const
42
+ {
43
+ if (!red && !green && !blue && !alpha)
44
+ return false;
45
+
46
+ if (red) *red = this->red;
47
+ if (green) *green = this->green;
48
+ if (blue) *blue = this->blue;
49
+ if (alpha) *alpha = this->alpha;
50
+ return true;
51
+ }
52
+
53
+ float*
54
+ Color::array ()
55
+ {
56
+ return (float*) this;
57
+ }
58
+
59
+ const float*
60
+ Color::array () const
61
+ {
62
+ return const_cast<Color*>(this)->array();
63
+ }
64
+
65
+ Color::operator bool () const
66
+ {
67
+ return red >= 0 && green >= 0 && blue >= 0 && alpha >= 0;
68
+ }
69
+
70
+ bool
71
+ Color::operator ! () const
72
+ {
73
+ return !operator bool();
74
+ }
75
+
76
+
77
+ }// Rays
data/src/colorspace.cpp CHANGED
@@ -1,7 +1,7 @@
1
1
  #include "rays/colorspace.h"
2
2
 
3
3
 
4
- #include <rays/helpers.h>
4
+ #include <xot/util.h>
5
5
 
6
6
 
7
7
  namespace Rays
@@ -55,7 +55,7 @@ namespace Rays
55
55
  int
56
56
  ColorSpace::Bpc () const
57
57
  {
58
- return bit2byte(bpc());
58
+ return Xot::bit2byte(bpc());
59
59
  }
60
60
 
61
61
  int
@@ -77,7 +77,7 @@ namespace Rays
77
77
  int
78
78
  ColorSpace::Bpp () const
79
79
  {
80
- return bit2byte(bpp());
80
+ return Xot::bit2byte(bpp());
81
81
  }
82
82
 
83
83
  int
data/src/exception.cpp CHANGED
@@ -1,21 +1,6 @@
1
1
  #include "rays/exception.h"
2
2
 
3
3
 
4
- #define VA_STRING(format, result) \
5
- String result; \
6
- do \
7
- { \
8
- if (format) \
9
- { \
10
- va_list args; \
11
- va_start(args, format); \
12
- result = Xot::stringf(format, args); \
13
- va_end(args); \
14
- } \
15
- } \
16
- while (false)
17
-
18
-
19
4
  namespace Rays
20
5
  {
21
6
 
@@ -23,7 +8,7 @@ namespace Rays
23
8
  RaysException::RaysException (const char* format, ...)
24
9
  : Super("")
25
10
  {
26
- VA_STRING(format, s);
11
+ XOT_STRINGF(format, s);
27
12
  text = s;
28
13
  }
29
14
 
@@ -39,9 +24,9 @@ namespace Rays
39
24
 
40
25
 
41
26
  void
42
- error (const char* format, ...)
27
+ rays_error (const char* format, ...)
43
28
  {
44
- VA_STRING(format, s);
29
+ XOT_STRINGF(format, s);
45
30
  throw RaysException(s.c_str());
46
31
  }
47
32
 
data/src/image.cpp CHANGED
@@ -81,7 +81,7 @@ namespace Rays
81
81
  const Bitmap&
82
82
  Image::bitmap () const
83
83
  {
84
- return const_cast<Image*>(this)->bitmap();
84
+ return const_cast<This*>(this)->bitmap();
85
85
  }
86
86
 
87
87
  Texture&
@@ -101,7 +101,7 @@ namespace Rays
101
101
  const Texture&
102
102
  Image::texture () const
103
103
  {
104
- return const_cast<Image*>(this)->texture();
104
+ return const_cast<This*>(this)->texture();
105
105
  }
106
106
 
107
107
  Image::operator bool () const
@@ -129,5 +129,12 @@ namespace Rays
129
129
  return *image;
130
130
  }
131
131
 
132
+ bool
133
+ save_image (const Image& image, const char* path)
134
+ {
135
+ if (!image || !path) return false;
136
+ return save_bitmap(image.bitmap(), path);
137
+ }
138
+
132
139
 
133
140
  }// Rays
data/src/matrix.cpp ADDED
@@ -0,0 +1,103 @@
1
+ #include "rays/matrix.h"
2
+
3
+
4
+ namespace Rays
5
+ {
6
+
7
+
8
+ Matrix::Matrix (float value)
9
+ {
10
+ set(value);
11
+ }
12
+
13
+ Matrix::Matrix (
14
+ float a1, float a2, float a3, float a4,
15
+ float b1, float b2, float b3, float b4,
16
+ float c1, float c2, float c3, float c4,
17
+ float d1, float d2, float d3, float d4)
18
+ {
19
+ set(a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4);
20
+ }
21
+
22
+ Matrix::Matrix (const float* elements, size_t size)
23
+ {
24
+ set(elements, size);
25
+ }
26
+
27
+ Matrix
28
+ Matrix::dup () const
29
+ {
30
+ return *this;
31
+ }
32
+
33
+ Matrix&
34
+ Matrix::set (float value)
35
+ {
36
+ return set(
37
+ value, 0, 0, 0,
38
+ 0, value, 0, 0,
39
+ 0, 0, value, 0,
40
+ 0, 0, 0, value);
41
+ }
42
+
43
+ Matrix&
44
+ Matrix::set (
45
+ float a1, float a2, float a3, float a4,
46
+ float b1, float b2, float b3, float b4,
47
+ float c1, float c2, float c3, float c4,
48
+ float d1, float d2, float d3, float d4)
49
+ {
50
+ this->a1 = a1; this->a2 = a2; this->a3 = a3; this->a4 = a4;
51
+ this->b1 = b1; this->b2 = b2; this->b3 = b3; this->b4 = b4;
52
+ this->c1 = c1; this->c2 = c2; this->c3 = c3; this->c4 = c4;
53
+ this->d1 = d1; this->d2 = d2; this->d3 = d3; this->d4 = d4;
54
+ return *this;
55
+ }
56
+
57
+ Matrix&
58
+ Matrix::set (const float* elements, size_t size)
59
+ {
60
+ if (size != 16) return *this;
61
+ float* e = array();
62
+ for (int i = 0; i < 16; ++i) *e++ = *elements++;
63
+ return *this;
64
+ }
65
+
66
+ float&
67
+ Matrix::at (int row, int column)
68
+ {
69
+ return array()[column * 4 + row];
70
+ }
71
+
72
+ float
73
+ Matrix::at (int row, int column) const
74
+ {
75
+ return const_cast<Matrix*>(this)->at(row, column);
76
+ }
77
+
78
+ float*
79
+ Matrix::array ()
80
+ {
81
+ return (float*) this;
82
+ }
83
+
84
+ const float*
85
+ Matrix::array () const
86
+ {
87
+ return const_cast<Matrix*>(this)->array();
88
+ }
89
+
90
+ float&
91
+ Matrix::operator [] (int index)
92
+ {
93
+ return array()[index];
94
+ }
95
+
96
+ float
97
+ Matrix::operator [] (int index) const
98
+ {
99
+ return const_cast<Matrix*>(this)->operator[](index);
100
+ }
101
+
102
+
103
+ }// Rays
data/src/painter.cpp CHANGED
@@ -2,7 +2,13 @@
2
2
 
3
3
 
4
4
  #include <math.h>
5
+ #include <list>
5
6
  #include <algorithm>
7
+ #include <rays/point.h>
8
+ #include <rays/bounds.h>
9
+ #include <rays/color.h>
10
+ #include <rays/matrix.h>
11
+ #include <rays/font.h>
6
12
  #include <rays/bitmap.h>
7
13
  #include <rays/texture.h>
8
14
  #include <rays/image.h>
@@ -12,181 +18,115 @@ namespace Rays
12
18
  {
13
19
 
14
20
 
21
+ enum ColorOrder
22
+ {
23
+
24
+ FILL = 0, STROKE
25
+
26
+ };// ColorOrder
27
+
28
+
15
29
  static const float PI = 3.141592653589793238462643383279f;
16
30
 
17
31
  static const float PI_2 = PI * 2;
18
32
 
19
33
 
20
34
  static void
21
- gl_clear_error ()
35
+ clear_error ()
22
36
  {
23
37
  glGetError();
24
38
  }
25
39
 
26
40
  static bool
27
- gl_no_error ()
41
+ is_error ()
28
42
  {
29
- return glGetError() == GL_NO_ERROR;
43
+ return glGetError() != GL_NO_ERROR;
30
44
  }
31
45
 
32
-
33
- struct Rect
46
+ static bool
47
+ is_error (GLenum error)
34
48
  {
35
-
36
- coord x, y, width, height;
37
-
38
- Rect ()
39
- : x(0), y(0), width(0), height(0)
40
- {
41
- }
42
-
43
- coord left () const
44
- {
45
- return x;
46
- }
47
-
48
- coord top () const
49
- {
50
- return y;
51
- }
52
-
53
- coord right () const
54
- {
55
- return x + width;
56
- }
57
-
58
- coord bottom () const
59
- {
60
- return y + height;
61
- }
62
-
63
- void set (coord x, coord y, coord width, coord height)
64
- {
65
- this->x = x;
66
- this->y = y;
67
- this->width = width;
68
- this->height = height;
69
- }
70
-
71
- bool get (coord* x, coord* y, coord* width, coord* height)
72
- {
73
- if (!x && !y && !width && !height)
74
- return false;
75
-
76
- if (x) *x = this->x;
77
- if (y) *y = this->y;
78
- if (width) *width = this->width;
79
- if (height) *height = this->height;
80
- return true;
81
- }
82
-
83
- coord* array () const {return (coord*) this;}
84
-
85
- operator bool () const
86
- {
87
- return width >= 0 && height >= 0;
88
- }
89
-
90
- bool operator ! () const
91
- {
92
- return !operator bool();
93
- }
94
-
95
- };// Rect
49
+ return glGetError() == error;
50
+ }
96
51
 
97
52
 
98
- struct Color
53
+ struct Attributes
99
54
  {
100
55
 
101
- float red, green, blue, alpha;
56
+ Bounds clip;
102
57
 
103
- Color ()
104
- : red(0), green(0), blue(0), alpha(0)
105
- {
106
- }
58
+ Color background, colors[2];
107
59
 
108
- void set (float red, float green, float blue, float alpha)
109
- {
110
- this->red = red;
111
- this->green = green;
112
- this->blue = blue;
113
- this->alpha = alpha;
114
- }
60
+ Font font;
115
61
 
116
- bool get (float* red, float* green, float* blue, float* alpha) const
62
+ void init ()
117
63
  {
118
- if (!red && !green && !blue && !alpha) return false;
119
- if (red) *red = this->red;
120
- if (green) *green = this->green;
121
- if (blue) *blue = this->blue;
122
- if (alpha) *alpha = this->alpha;
123
- return true;
64
+ clip .set(-1);
65
+ background .set(0, 0);
66
+ colors[FILL] .set(0, 0);
67
+ colors[STROKE] .set(0, 0);
68
+ font = default_font();
124
69
  }
125
70
 
126
- float* array () const {return (float*) this;}
127
-
128
- };// Color
71
+ };// Attributes
129
72
 
130
73
 
131
74
  struct Painter::Data
132
75
  {
133
76
 
134
- Rect viewport, clip;
77
+ Bounds viewport;
78
+
79
+ Attributes attrs;
135
80
 
136
- Color clear, colors[2];
81
+ std::list<Attributes> attrs_stack;
137
82
 
138
- bool painting, drawing, clipping;
83
+ bool painting, drawing;
139
84
 
140
85
  Image textimage;
141
86
 
87
+ mutable Matrix matrix_tmp;
88
+
142
89
  Data ()
143
- : painting(false), drawing(false), clipping(false),
144
- textimage(1, 1, GRAY, true)
90
+ : painting(false), drawing(false), textimage(1, 1, GRAY, true)
145
91
  {
92
+ attrs.init();
146
93
  }
147
94
 
148
- bool use_color (size_t i) const
95
+ bool use_color (size_t i)
149
96
  {
150
- gl_clear_error();
97
+ clear_error();
151
98
 
152
- const Color& c = colors[i];
153
- if (c.alpha <= 0) return false;
99
+ const Color& col = attrs.colors[i];
100
+ if (col.alpha <= 0) return false;
154
101
 
155
- glColor4fv(c.array());
156
- return gl_no_error();
102
+ glColor4fv(col.array());
103
+ return !is_error();
157
104
  }
158
105
 
159
106
  bool update_clip ()
160
107
  {
161
- gl_clear_error();
108
+ clear_error();
162
109
 
163
- if (clip)
110
+ if (attrs.clip)
164
111
  {
165
- if (clipping) return true;
166
112
  glEnable(GL_SCISSOR_TEST);
167
- clipping = true;
113
+ glScissor(
114
+ attrs.clip.x,
115
+ viewport.height - attrs.clip.height - attrs.clip.y,
116
+ attrs.clip.width,
117
+ attrs.clip.height);
168
118
  }
169
119
  else
170
120
  {
171
- if (!clipping) return true;
172
121
  glDisable(GL_SCISSOR_TEST);
173
- clipping = false;
174
122
  }
175
123
 
176
- return gl_no_error();
124
+ return !is_error();
177
125
  }
178
126
 
179
127
  };// Painter::Data
180
128
 
181
129
 
182
- enum ColorOrder
183
- {
184
-
185
- FILL = 0, STROKE
186
-
187
- };// ColorOrder
188
-
189
-
190
130
  Painter::Painter ()
191
131
  {
192
132
  }
@@ -198,27 +138,31 @@ namespace Rays
198
138
  bool
199
139
  Painter::canvas (coord x, coord y, coord width, coord height)
200
140
  {
201
- if (self->painting || width < 0 || height < 0)
202
- return false;
141
+ return canvas(Bounds(x, y, -100, width, height, 200));
142
+ }
203
143
 
204
- self->viewport.set(x, y, width, height);
144
+ bool
145
+ Painter::canvas (coord x, coord y, coord z, coord width, coord height, coord depth)
146
+ {
147
+ return canvas(Bounds(x, y, z, width, height, depth));
148
+ }
149
+
150
+ bool
151
+ Painter::canvas (const Bounds& bounds)
152
+ {
153
+ if (self->painting || !bounds) return false;
205
154
 
206
- glViewport(
207
- (int) self->viewport.x, (int) self->viewport.y,
208
- (int) self->viewport.width, (int) self->viewport.height);
155
+ const Bounds& b = self->viewport = bounds;
156
+
157
+ glViewport((int) b.x, (int) b.y, (int) b.width, (int) b.height);
209
158
 
210
159
  glMatrixMode(GL_PROJECTION);
211
160
  glLoadIdentity();
212
-
213
- glOrtho(
214
- self->viewport.left(), self->viewport.right(),
215
- self->viewport.top(), self->viewport.bottom(),
216
- -100, 100);
217
- glRotatef(180, 1, 0, 0);
218
- glTranslatef(0, -self->viewport.height, 0);
161
+ glOrtho(b.x, b.x + b.width, b.y + b.height, b.y, b.z, b.z + b.depth);
219
162
 
220
163
  glMatrixMode(GL_MODELVIEW);
221
164
  glLoadIdentity();
165
+ glTranslatef(0.375f, 0.375f, 0);
222
166
 
223
167
  return true;
224
168
  }
@@ -228,6 +172,8 @@ namespace Rays
228
172
  {
229
173
  if (self->painting) return false;
230
174
 
175
+ push_attrs();
176
+
231
177
  glEnable(GL_CULL_FACE);
232
178
  glEnable(GL_BLEND);
233
179
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -252,21 +198,7 @@ namespace Rays
252
198
  glDisable(GL_BLEND);
253
199
  glDisable(GL_CULL_FACE);
254
200
 
255
- return true;
256
- }
257
-
258
- bool
259
- Painter::push_matrix ()
260
- {
261
- glPushMatrix();
262
- return true;
263
- }
264
-
265
- bool
266
- Painter::pop_matrix ()
267
- {
268
- glPopMatrix();
269
- return true;
201
+ return pop_attrs();
270
202
  }
271
203
 
272
204
 
@@ -278,13 +210,19 @@ namespace Rays
278
210
 
279
211
  if (!begin_shape(LINES)) return false;
280
212
  bool ret =
281
- vertex(x1, y1) &&
282
- vertex(x2, y2);
213
+ add_vertex(x1, y1) &&
214
+ add_vertex(x2, y2);
283
215
  if (!end_shape()) return false;
284
216
 
285
217
  return ret;
286
218
  }
287
219
 
220
+ bool
221
+ Painter::line (const Point& p1, const Point& p2)
222
+ {
223
+ return line(p1.x, p1.y, p2.x, p2.y);
224
+ }
225
+
288
226
  bool
289
227
  Painter::rect (coord x, coord y, coord width, coord height)
290
228
  {
@@ -292,8 +230,10 @@ namespace Rays
292
230
 
293
231
  if (!self->painting) return false;
294
232
 
295
- coord x2 = x + width;
296
- coord y2 = y + height;
233
+ if (width <= 0 || height <= 0) return true;
234
+
235
+ coord x2 = x + width - 1;
236
+ coord y2 = y + height - 1;
297
237
 
298
238
  bool ret = true;
299
239
  for (int i = 0; i < 2; ++i)
@@ -301,17 +241,25 @@ namespace Rays
301
241
  if (!self->use_color(i)) continue;
302
242
 
303
243
  if (!begin_shape(TYPES[i])) return false;
244
+ coord xx = x2 + 1 - i;
245
+ coord yy = y2 + 1 - i;
304
246
  ret &=
305
- vertex(x, y) &&
306
- vertex(x, y2) &&
307
- vertex(x2, y2) &&
308
- vertex(x2, y);
247
+ add_vertex(x, y) &&
248
+ add_vertex(x, yy) &&
249
+ add_vertex(xx, yy) &&
250
+ add_vertex(xx, y);
309
251
  if (!end_shape()) return false;
310
252
  }
311
253
 
312
254
  return ret;
313
255
  }
314
256
 
257
+ bool
258
+ Painter::rect (const Bounds& bounds)
259
+ {
260
+ return rect(bounds.x, bounds.y, bounds.width, bounds.height);
261
+ }
262
+
315
263
  static bool
316
264
  draw_ellipse (
317
265
  Painter* painter,
@@ -348,7 +296,7 @@ namespace Rays
348
296
  if (!painter->begin_shape(types[i])) return false;
349
297
 
350
298
  if (!hole)
351
- ret &= painter->vertex(x, y);
299
+ ret &= painter->add_vertex(x, y);
352
300
 
353
301
  for (int seg = 0; seg <= (int) nsegment; ++seg)
354
302
  {
@@ -357,8 +305,8 @@ namespace Rays
357
305
  float xx = cos(radian);
358
306
  float yy = -sin(radian);
359
307
  if (hole)
360
- ret &= painter->vertex(x + xx * radius_x_min, y + yy * radius_y_min);
361
- ret &= painter->vertex(x + xx * radius_x, y + yy * radius_y);
308
+ ret &= painter->add_vertex(x + xx * radius_x_min, y + yy * radius_y_min);
309
+ ret &= painter->add_vertex(x + xx * radius_x, y + yy * radius_y);
362
310
  }
363
311
 
364
312
  if (!painter->end_shape()) return false;
@@ -371,25 +319,59 @@ namespace Rays
371
319
 
372
320
  bool
373
321
  Painter::ellipse (
374
- coord x, coord y, coord width, coord height, coord radius_min,
375
- uint nsegment)
322
+ coord x, coord y, coord width, coord height,
323
+ coord radius_min, uint nsegment)
376
324
  {
377
325
  if (nsegment <= 0) nsegment = ELLIPSE_NSEGMENT;
378
326
  return draw_ellipse(
379
327
  this, x, y, width, height, 0, 360, radius_min, nsegment);
380
328
  }
381
329
 
330
+ bool
331
+ Painter::ellipse (const Bounds& bounds, coord radius_min, uint nsegment)
332
+ {
333
+ return ellipse(
334
+ bounds.x, bounds.y, bounds.width, bounds.height, radius_min, nsegment);
335
+ }
336
+
337
+ bool
338
+ Painter::ellipse (
339
+ const Point& center, coord radius, coord radius_min, uint nsegment)
340
+ {
341
+ return ellipse(
342
+ center.x, center.y, radius * 2, radius * 2, radius_min, nsegment);
343
+ }
344
+
382
345
  bool
383
346
  Painter::arc (
384
347
  coord x, coord y, coord width, coord height,
385
- float angle_from, float angle_to, coord radius_min,
386
- uint nsegment)
348
+ float angle_from, float angle_to, coord radius_min, uint nsegment)
387
349
  {
388
350
  if (nsegment <= 0) nsegment = ELLIPSE_NSEGMENT;
389
351
  return draw_ellipse(
390
352
  this, x, y, width, height, angle_from, angle_to, radius_min, nsegment);
391
353
  }
392
354
 
355
+ bool
356
+ Painter::arc (
357
+ const Bounds& bounds,
358
+ float angle_from, float angle_to, coord radius_min, uint nsegment)
359
+ {
360
+ return arc(
361
+ bounds.x, bounds.y, bounds.width, bounds.height,
362
+ angle_from, angle_to, radius_min, nsegment);
363
+ }
364
+
365
+ bool
366
+ Painter::arc (
367
+ const Point& center, coord radius,
368
+ float angle_from, float angle_to, coord radius_min, uint nsegment)
369
+ {
370
+ return arc(
371
+ center.x, center.y, radius * 2, radius * 2,
372
+ angle_from, angle_to, radius_min, nsegment);
373
+ }
374
+
393
375
  static bool
394
376
  draw_image (
395
377
  Painter* painter, const Texture& tex,
@@ -404,11 +386,11 @@ namespace Rays
404
386
  if (!painter || !painter->self->painting)
405
387
  return false;
406
388
 
407
- coord x2 = x + width;
408
- coord y2 = y + height;
389
+ coord x2 = x + width - 1;
390
+ coord y2 = y + height - 1;
409
391
 
410
392
  glEnable(GL_TEXTURE_2D);
411
- painter->texture(tex);
393
+ painter->set_texture(tex);
412
394
 
413
395
  bool ret = true;
414
396
  for (int i = 0; i < 2; ++i)
@@ -422,10 +404,10 @@ namespace Rays
422
404
 
423
405
  if (!painter->begin_shape(TYPES[i])) return false;
424
406
  ret &=
425
- painter->vertex(x, y, s_min, t_min) &&
426
- painter->vertex(x, y2, s_min, t_max) &&
427
- painter->vertex(x2, y2, s_max, t_max) &&
428
- painter->vertex(x2, y, s_max, t_min);
407
+ painter->add_vertex(x, y, s_min, t_min) &&
408
+ painter->add_vertex(x, y2, s_min, t_max) &&
409
+ painter->add_vertex(x2, y2, s_max, t_max) &&
410
+ painter->add_vertex(x2, y, s_max, t_min);
429
411
  if (!painter->end_shape()) return false;
430
412
  }
431
413
 
@@ -449,6 +431,12 @@ namespace Rays
449
431
  x, y, tex.width(), tex.height());
450
432
  }
451
433
 
434
+ bool
435
+ Painter::image (const Image& image_, const Point& position)
436
+ {
437
+ return image(image_, position.x, position.y);
438
+ }
439
+
452
440
  bool
453
441
  Painter::image (
454
442
  const Image& image_, coord x, coord y, coord width, coord height)
@@ -464,6 +452,13 @@ namespace Rays
464
452
  x, y, width, height);
465
453
  }
466
454
 
455
+ bool
456
+ Painter::image (
457
+ const Image& image_, const Bounds& bounds)
458
+ {
459
+ return image(image_, bounds.x, bounds.y, bounds.width, bounds.height);
460
+ }
461
+
467
462
  bool
468
463
  Painter::image (
469
464
  const Image& image_,
@@ -483,6 +478,16 @@ namespace Rays
483
478
  dest_x, dest_y, dest_width, dest_height);
484
479
  }
485
480
 
481
+ bool
482
+ Painter::image (
483
+ const Image& image_, const Bounds& src_bounds, const Point& dest_position)
484
+ {
485
+ return image(
486
+ image_,
487
+ src_bounds.x, src_bounds.y, src_bounds.width, src_bounds.height,
488
+ dest_position.x, dest_position.y);
489
+ }
490
+
486
491
  bool
487
492
  Painter::image (
488
493
  const Image& image_,
@@ -502,6 +507,16 @@ namespace Rays
502
507
  dest_x, dest_y, dest_width, dest_height);
503
508
  }
504
509
 
510
+ bool
511
+ Painter::image (
512
+ const Image& image_, const Bounds& src_bounds, const Bounds& dest_bounds)
513
+ {
514
+ return image(
515
+ image_,
516
+ src_bounds.x, src_bounds.y, src_bounds.width, src_bounds.height,
517
+ dest_bounds.x, dest_bounds.y, dest_bounds.width, dest_bounds.height);
518
+ }
519
+
505
520
  static bool
506
521
  draw_text (
507
522
  Painter* painter, const char* str, coord str_width, coord str_height,
@@ -514,15 +529,17 @@ namespace Rays
514
529
  return false;
515
530
 
516
531
  Painter::Data* self = painter->self.get();
532
+ int tex_w = ceil(str_width);
533
+ int tex_h = ceil(str_height);
517
534
 
518
535
  if (
519
- self->textimage.width() < str_width ||
520
- self->textimage.height() < str_height)
536
+ self->textimage.width() < tex_w ||
537
+ self->textimage.height() < tex_h)
521
538
  {
522
- coord w = std::max((coord) self->textimage.width(), str_width);
523
- coord h = std::max((coord) self->textimage.height(), str_height);
524
539
  self->textimage = Image(
525
- w + 1, h + 1, self->textimage.color_space(),
540
+ std::max(self->textimage.width(), tex_w),
541
+ std::max(self->textimage.height(), tex_h),
542
+ self->textimage.color_space(),
526
543
  self->textimage.alpha_texture());
527
544
  }
528
545
 
@@ -534,44 +551,93 @@ namespace Rays
534
551
  const Texture& tex = self->textimage.texture();
535
552
  if (!tex) return false;
536
553
 
537
- float s = tex.s_max() / tex.width();
538
- float t = tex.t_max() / tex.height();
539
- return draw_image(
554
+ #ifdef DEBUG
555
+ save_image(self->textimage, "/Users/snori/font.png");
556
+
557
+ painter->push_attrs();
558
+ {
559
+ coord asc, desc, lead;
560
+ font.get_height(NULL, &asc, &desc, &lead);
561
+ //printf("%f %f %f %f \n", str_height, asc, desc, lead);
562
+
563
+ painter->set_stroke(0.5, 0.5, 1);
564
+ painter->no_fill();
565
+ painter->rect(x - 1, y - 1, str_width + 2, str_height + 2);
566
+
567
+ coord yy = y;
568
+ painter->set_stroke(1, 0.5, 0.5, 0.4);
569
+ painter->rect(x, yy, str_width, asc);//str_height);
570
+
571
+ yy += asc;
572
+ painter->set_stroke(1, 1, 0.5, 0.4);
573
+ painter->rect(x, yy, str_width, desc);
574
+
575
+ yy += desc;
576
+ painter->set_stroke(1, 0.5, 1, 0.4);
577
+ painter->rect(x, yy, str_width, lead);
578
+ }
579
+ painter->pop_attrs();
580
+ #endif
581
+
582
+ bool ret = draw_image(
540
583
  painter, tex,
541
- 0, 0, str_width * s, str_height * t,
542
- x, y, width, height,
584
+ 0, 0, tex.s(str_width - 1), tex.t(str_height - 1),
585
+ x, y, width, height,
543
586
  true);
587
+
588
+ return ret;
544
589
  }
545
590
 
546
591
  bool
547
- Painter::text (const char* str, coord x, coord y, const Font& font)
592
+ Painter::text (const char* str, coord x, coord y, const Font* font)
548
593
  {
549
- if (!str || !font) return false;
594
+ if (!str) return false;
550
595
 
551
596
  if (*str == '\0') return true;
552
597
 
598
+ if (!font) font = &self->attrs.font;
599
+ if (!*font) return false;
600
+
553
601
  coord w = 0, h = 0;
554
- if (!font.get_extent(&w, &h, str))
602
+ if (!font->get_width(&w, str) || !font->get_height(&h))
555
603
  return false;
556
604
 
557
- return draw_text(
558
- this, str, w, h, x, y, w, h, font);
605
+ w = ceil(w);
606
+ h = ceil(h);
607
+ return draw_text(this, str, w, h, x, y, w, h, *font);
608
+ }
609
+
610
+ bool
611
+ Painter::text (const char* str, const Point& position, const Font* font)
612
+ {
613
+ return text(str, position.x, position.y, font);
559
614
  }
560
615
 
561
616
  bool
562
617
  Painter::text (
563
618
  const char* str, coord x, coord y, coord width, coord height,
564
- const Font& font)
619
+ const Font* font)
565
620
  {
566
- if (!str || !font) return false;
621
+ if (!str) return false;
567
622
 
568
623
  if (*str == '\0') return true;
569
624
 
625
+ if (!font) font = &self->attrs.font;
626
+ if (!*font) return false;
627
+
570
628
  coord w = 0, h = 0;
571
- if (!font.get_extent(&w, &h, str))
629
+ if (!font->get_width(&w, str) || !font->get_height(&h))
572
630
  return false;
573
631
 
574
- return draw_text(this, str, w, h, x, y, width, height, font);
632
+ w = ceil(w);
633
+ h = ceil(h);
634
+ return draw_text(this, str, w, h, x, y, width, height, *font);
635
+ }
636
+
637
+ bool
638
+ Painter::text (const char* str, const Bounds& bounds, const Font* font)
639
+ {
640
+ return text(str, bounds.x, bounds.y, bounds.width, bounds.height, font);
575
641
  }
576
642
 
577
643
  bool
@@ -579,91 +645,106 @@ namespace Rays
579
645
  {
580
646
  if (!self->painting) return false;
581
647
 
648
+ const Color& c = self->attrs.background;
649
+ glClearColor(c.red, c.green, c.blue, c.alpha);
582
650
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
583
651
  return true;
584
652
  }
585
653
 
586
654
  bool
587
- Painter::get_clear (float* red, float* green, float* blue, float* alpha)
655
+ Painter::set_background (float red, float green, float blue, float alpha)
588
656
  {
589
- return self->clear.get(red, green, blue, alpha);
657
+ self->attrs.background.set(red, green, blue, alpha);
658
+ return true;
590
659
  }
591
660
 
592
661
  bool
593
- Painter::set_clear (float red, float green, float blue, float alpha)
662
+ Painter::set_background (const Color& color)
594
663
  {
595
- self->clear.set(red, green, blue, alpha);
596
- glClearColor(red, green, blue, alpha);
664
+ self->attrs.background = color;
597
665
  return true;
598
666
  }
599
667
 
600
668
  bool
601
- Painter::no_clear ()
669
+ Painter::no_background ()
602
670
  {
603
- return set_clear(
604
- self->clear.red, self->clear.green, self->clear.blue, 0);
671
+ self->attrs.background.alpha = 0;
672
+ return true;
605
673
  }
606
674
 
607
- bool
608
- Painter::get_fill (float* red, float* green, float* blue, float* alpha)
675
+ const Color&
676
+ Painter::background () const
609
677
  {
610
- return self->colors[FILL].get(red, green, blue, alpha);
678
+ return self->attrs.background;
611
679
  }
612
680
 
613
681
  bool
614
682
  Painter::set_fill (float red, float green, float blue, float alpha)
615
683
  {
616
- self->colors[FILL].set(red, green, blue, alpha);
684
+ self->attrs.colors[FILL].set(red, green, blue, alpha);
617
685
  return true;
618
686
  }
619
687
 
620
688
  bool
621
- Painter::no_fill ()
689
+ Painter::set_fill (const Color& color)
622
690
  {
623
- self->colors[FILL].alpha = 0;
691
+ self->attrs.colors[FILL] = color;
624
692
  return true;
625
693
  }
626
694
 
627
695
  bool
628
- Painter::get_stroke (float* red, float* green, float* blue, float* alpha)
696
+ Painter::no_fill ()
629
697
  {
630
- return self->colors[STROKE].get(red, green, blue, alpha);
698
+ self->attrs.colors[FILL].alpha = 0;
699
+ return true;
700
+ }
701
+
702
+ const Color&
703
+ Painter::fill () const
704
+ {
705
+ return self->attrs.colors[FILL];
631
706
  }
632
707
 
633
708
  bool
634
709
  Painter::set_stroke (float red, float green, float blue, float alpha)
635
710
  {
636
- self->colors[STROKE].set(red, green, blue, alpha);
711
+ self->attrs.colors[STROKE].set(red, green, blue, alpha);
637
712
  return true;
638
713
  }
639
714
 
640
715
  bool
641
- Painter::no_stroke ()
716
+ Painter::set_stroke (const Color& color)
642
717
  {
643
- self->colors[STROKE].alpha = 0;
718
+ self->attrs.colors[STROKE] = color;
644
719
  return true;
645
720
  }
646
721
 
647
722
  bool
648
- Painter::get_clip (coord* x, coord* y, coord* width, coord* height)
723
+ Painter::no_stroke ()
724
+ {
725
+ self->attrs.colors[STROKE].alpha = 0;
726
+ return true;
727
+ }
728
+
729
+ const Color&
730
+ Painter::stroke () const
649
731
  {
650
- return self->clip.get(x, y, width, height);
732
+ return self->attrs.colors[STROKE];
651
733
  }
652
734
 
653
735
  bool
654
736
  Painter::set_clip (coord x, coord y, coord width, coord height)
655
737
  {
656
- self->clip.set(x, y, width, height);
657
- if (!self->update_clip())
658
- return false;
738
+ return set_clip(Bounds(x, y, width, height));
739
+ }
659
740
 
660
- if (self->clip)
661
- {
662
- glScissor(
663
- self->clip.x, -self->clip.y, self->clip.width, self->clip.height);
664
- }
741
+ bool
742
+ Painter::set_clip (const Bounds& bounds)
743
+ {
744
+ if (bounds == self->attrs.clip) return true;
665
745
 
666
- return true;
746
+ self->attrs.clip = bounds;
747
+ return self->update_clip();
667
748
  }
668
749
 
669
750
  bool
@@ -672,6 +753,154 @@ namespace Rays
672
753
  return set_clip(0, 0, -1, -1);
673
754
  }
674
755
 
756
+ const Bounds&
757
+ Painter::clip () const
758
+ {
759
+ return self->attrs.clip;
760
+ }
761
+
762
+ bool
763
+ Painter::set_font (const Font& font)
764
+ {
765
+ self->attrs.font = font;
766
+ return true;
767
+ }
768
+
769
+ const Font&
770
+ Painter::font () const
771
+ {
772
+ return self->attrs.font;
773
+ }
774
+
775
+ bool
776
+ Painter::push_attrs ()
777
+ {
778
+ //glPushAttrib(GL_ALL_ATTRIB_BITS);
779
+ self->attrs_stack.push_back(self->attrs);
780
+ return true;
781
+ }
782
+
783
+ bool
784
+ Painter::pop_attrs ()
785
+ {
786
+ if (self->attrs_stack.empty()) return false;
787
+
788
+ self->attrs = self->attrs_stack.back();
789
+ self->attrs_stack.pop_back();
790
+ self->update_clip();
791
+
792
+ //glPopAttrib();
793
+ return true;
794
+ }
795
+
796
+
797
+ bool
798
+ Painter::translate (coord x, coord y, coord z)
799
+ {
800
+ glTranslatef(x, y, z);
801
+ return !is_error();
802
+ }
803
+
804
+ bool
805
+ Painter::translate (const Point& value)
806
+ {
807
+ return translate(value.x, value.y, value.z);
808
+ }
809
+
810
+ bool
811
+ Painter::scale (coord x, coord y, coord z)
812
+ {
813
+ glScalef(x, y, z);
814
+ return !is_error();
815
+ }
816
+
817
+ bool
818
+ Painter::scale (const Point& value)
819
+ {
820
+ return scale(value.x, value.y, value.z);
821
+ }
822
+
823
+ bool
824
+ Painter::rotate (float angle, coord x, coord y, coord z)
825
+ {
826
+ glRotatef(angle, x, y, z);
827
+ return !is_error();
828
+ }
829
+
830
+ bool
831
+ Painter::rotate (float angle, const Point& center)
832
+ {
833
+ return rotate(angle, center.x, center.y, center.z);
834
+ }
835
+
836
+ bool
837
+ Painter::set_matrix (float value)
838
+ {
839
+ if (value == 1)
840
+ {
841
+ glLoadIdentity();
842
+ return !is_error();
843
+ }
844
+
845
+ return set_matrix(
846
+ value, 0, 0, 0,
847
+ 0, value, 0, 0,
848
+ 0, 0, value, 0,
849
+ 0, 0, 0, value);
850
+ }
851
+
852
+ bool
853
+ Painter::set_matrix (
854
+ float a1, float a2, float a3, float a4,
855
+ float b1, float b2, float b3, float b4,
856
+ float c1, float c2, float c3, float c4,
857
+ float d1, float d2, float d3, float d4)
858
+ {
859
+ float array[] = {
860
+ a1, a2, a3, a4,
861
+ b1, b2, b3, b4,
862
+ c1, c2, c3, c4,
863
+ d1, d2, d3, d4
864
+ };
865
+ return set_matrix(array);
866
+ }
867
+
868
+ bool
869
+ Painter::set_matrix (const float* elements)
870
+ {
871
+ if (!elements) return false;
872
+ glLoadMatrixf(elements);
873
+ return !is_error();
874
+ }
875
+
876
+ bool
877
+ Painter::set_matrix (const Matrix& matrix)
878
+ {
879
+ return set_matrix(matrix.array());
880
+ }
881
+
882
+ const Matrix&
883
+ Painter::matrix () const
884
+ {
885
+ glGetFloatv(GL_MODELVIEW_MATRIX, self->matrix_tmp.array());
886
+ if (is_error(GL_INVALID_ENUM)) self->matrix_tmp.set(0);
887
+ return self->matrix_tmp;
888
+ }
889
+
890
+ bool
891
+ Painter::push_matrix ()
892
+ {
893
+ glPushMatrix();
894
+ return !is_error(GL_STACK_OVERFLOW);
895
+ }
896
+
897
+ bool
898
+ Painter::pop_matrix ()
899
+ {
900
+ glPopMatrix();
901
+ return !is_error(GL_STACK_UNDERFLOW);
902
+ }
903
+
675
904
 
676
905
  bool
677
906
  Painter::begin_shape (ShapeType type)
@@ -698,7 +927,7 @@ namespace Rays
698
927
  }
699
928
 
700
929
  bool
701
- Painter::color (float red, float green, float blue, float alpha)
930
+ Painter::set_color (float red, float green, float blue, float alpha)
702
931
  {
703
932
  if (!self->drawing) return false;
704
933
 
@@ -707,7 +936,16 @@ namespace Rays
707
936
  }
708
937
 
709
938
  bool
710
- Painter::texture (const Texture& tex)
939
+ Painter::set_color (const Color& color)
940
+ {
941
+ if (!self->drawing) return false;
942
+
943
+ glColor4fv(color.array());
944
+ return true;
945
+ }
946
+
947
+ bool
948
+ Painter::set_texture (const Texture& tex)
711
949
  {
712
950
  if (!self->drawing) return false;
713
951
 
@@ -725,13 +963,13 @@ namespace Rays
725
963
  }
726
964
 
727
965
  bool
728
- Painter::vertex (coord x, coord y)
966
+ Painter::add_vertex (coord x, coord y)
729
967
  {
730
- return vertex(x, y, 0);
968
+ return add_vertex(x, y, 0);
731
969
  }
732
970
 
733
971
  bool
734
- Painter::vertex (coord x, coord y, coord z)
972
+ Painter::add_vertex (coord x, coord y, coord z)
735
973
  {
736
974
  if (!self->drawing) return false;
737
975
 
@@ -740,20 +978,33 @@ namespace Rays
740
978
  }
741
979
 
742
980
  bool
743
- Painter::vertex (coord x, coord y, coord texcoord_s, coord texcoord_t)
981
+ Painter::add_vertex (const Point& pos)
744
982
  {
745
- return vertex(x, y, 0, texcoord_s, texcoord_t);
983
+ return add_vertex(pos.x, pos.y, pos.z);
746
984
  }
747
985
 
748
986
  bool
749
- Painter::vertex (coord x, coord y, coord z, coord texcoord_s, coord texcoord_t)
987
+ Painter::add_vertex (coord x, coord y, coord tex_s, coord tex_t)
988
+ {
989
+ return add_vertex(x, y, 0, tex_s, tex_t);
990
+ }
991
+
992
+ bool
993
+ Painter::add_vertex (coord x, coord y, coord z, coord tex_s, coord tex_t)
750
994
  {
751
995
  if (!self->drawing) return false;
752
996
 
753
- glTexCoord2f(texcoord_s, texcoord_t);
754
- return vertex(x, y, z);
997
+ glTexCoord2f(tex_s, tex_t);
998
+ return add_vertex(x, y, z);
999
+ }
1000
+
1001
+ bool
1002
+ Painter::add_vertex (const Point& pos, coord tex_s, coord tex_t)
1003
+ {
1004
+ return add_vertex(pos.x, pos.y, pos.z, tex_s, tex_t);
755
1005
  }
756
1006
 
1007
+
757
1008
  Painter::operator bool () const
758
1009
  {
759
1010
  return self->viewport;