rays 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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;