1 // Copyright Timothy Goya 2007.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #include <unison/video/Texture.hpp>
7 #include <unison/video/Window.hpp>
8 #include <unison/video/Renderers.hpp>
9 #include <unison/video/Color.hpp>
10 #include <unison/video/sdl/Blitters.hpp>
11 #include <unison/video/backend/Renderer.hpp>
12 #include <unison/video/backend/Texture.hpp>
13 #include <unison/vfs/stream.hpp>
26 Surface::Surface(const std::string &filename) :
29 *this = Renderers::get().get_renderer().load_surface(filename);
32 Surface::Surface(const std::string &filename, const Color &colorkey) :
35 *this = Renderers::get().get_renderer().load_surface(filename, colorkey);
38 Surface::Surface(const Area &size) :
39 pixels(new PixelBuffer(size))
44 Surface::Surface(const Surface &rhs) :
62 Surface &Surface::operator =(const Surface &rhs)
76 void Surface::save(const std::string &filename) const
78 Renderers::get().get_renderer().save_surface(*this, filename);
81 void Surface::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
85 Renderers::get().get_renderer().blit(src, src_rect, *this, dst_pos, options);
88 void Surface::blit(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
92 Renderers::get().get_renderer().blit(Backend::Texture::get_texture(src.get_id()), src_rect, *this, dst_pos, options);
95 void Surface::fill(const Color &color, const Rect &rect)
99 Renderers::get().get_renderer().fill(*this, color, rect);
102 void Surface::fill_blend(const Color &color, const Rect &rect)
106 Renderers::get().get_renderer().fill_blend(*this, color, rect);
111 Color merge(const Color &color0, const Color &color1, int rem, int total)
113 return Color((color0.red * (total - rem) + color1.red * rem) / total,
114 (color0.green * (total - rem) + color1.green * rem) / total,
115 (color0.blue * (total - rem) + color1.blue * rem) / total,
116 (color0.alpha * (total - rem) + color1.alpha * rem) / total);
120 Surface Surface::scale(unsigned int numerator, unsigned int denominator) const
123 if(numerator == denominator)
129 Surface scaled(get_size() * numerator / denominator);
130 for(unsigned int y = 0;y < scaled.get_size().y;y++)
132 for(unsigned int x = 0;x < scaled.get_size().x;x++)
134 unsigned int srcx = x * denominator / numerator;
135 unsigned int srcy = y * denominator / numerator;
136 //scaled.set_pixel(Point(x, y), get_pixel(Point(srcx, srcy)));
137 int incx = (srcx + 1 == get_size().x ? 0 : 1);
138 int incy = (srcy + 1 == get_size().y ? 0 : 1);
139 Color color00 = get_pixel(srcx, srcy);
140 Color color01 = get_pixel(srcx + incx, srcy);
141 Color color10 = get_pixel(srcx, srcy + incy);
142 Color color11 = get_pixel(srcx + incx, srcy + incy);
143 int remx = x * denominator % numerator;
144 Color color0 = merge(color00, color01, remx, numerator);
145 Color color1 = merge(color10, color11, remx, numerator);
146 int remy = y * denominator % numerator;
147 Color color = merge(color0, color1, remy, numerator);
148 scaled.get_pixel(x, y) = color;
155 Surface Surface::h_flip() const
158 Surface flipped(get_size());
159 for(unsigned int y = 0;y < get_size().y;y++)
161 for(unsigned int x = 0;x < get_size().x;x++)
163 flipped.get_pixel(x, y) = get_pixel(get_size().x - x - 1, y);
169 Surface Surface::v_flip() const
172 Surface flipped(get_size());
173 for(unsigned int y = 0;y < get_size().y;y++)
175 for(unsigned int x = 0;x < get_size().x;x++)
177 flipped.get_pixel(x, y) = get_pixel(x, get_size().y - y - 1);
183 Surface Surface::modulate(const Color &color) const
186 if(color == Color::WHITE)
192 Surface modulated(get_size());
193 for(unsigned int y = 0;y < get_size().y;y++)
195 for(unsigned int x = 0;x < get_size().x;x++)
197 Color pixel = get_pixel(x, y);
198 pixel.red = pixel.red * color.red / 0xff;
199 pixel.green = pixel.green * color.green / 0xff;
200 pixel.blue = pixel.blue * color.blue / 0xff;
201 pixel.alpha = pixel.alpha * color.alpha / 0xff;
202 modulated.get_pixel(x, y) = pixel;
209 Surface Surface::modulate(unsigned char alpha) const
218 Surface modulated(get_size());
219 for(unsigned int y = 0;y < get_size().y;y++)
221 for(unsigned int x = 0;x < get_size().x;x++)
223 Color pixel = get_pixel(x, y);
224 pixel.alpha = pixel.alpha * alpha / 0xff;
225 modulated.get_pixel(x, y) = pixel;
234 if(pixels && pixels->refcount > 1)
236 PixelBuffer *original = pixels;
237 pixels = new PixelBuffer(pixels->size);
238 memcpy(pixels->buffer, original->buffer, pixels->size.x * pixels->size.y * sizeof(Color));