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/Blitters.hpp>
7 #include <unison/video/Surface.hpp>
15 void Blitters::blit_upper(const Surface &src, Rect src_rect, Surface &dst, Point dst_pos, void (*blit_lower)(const Surface &, const Rect &, Surface &, const Point &))
17 assert(src.get_pixels());
18 assert(dst.get_pixels());
20 if(src_rect == Rect())
22 src_rect.size.x = src.get_size().x;
23 src_rect.size.y = src.get_size().y;
27 if(src_rect.size.x < (unsigned int) -dst_pos.x)
31 src_rect.pos.x += -dst_pos.x;
32 src_rect.size.x += dst_pos.x;
37 if(src_rect.size.y < (unsigned int) -dst_pos.y)
41 src_rect.pos.y += -dst_pos.y;
42 src_rect.size.y += dst_pos.y;
45 if(src_rect.pos.x < 0)
47 if(src_rect.size.x < (unsigned int) -src_rect.pos.x)
51 src_rect.size.x += src_rect.pos.x;
54 if(src_rect.pos.y < 0)
56 if(src_rect.size.y < (unsigned int) -src_rect.pos.y)
60 src_rect.size.y += src_rect.pos.y;
63 if(src_rect.get_right() > (int) src.get_size().x)
65 src_rect.size.x = src.get_size().x - src_rect.pos.x;
67 if(src_rect.get_bottom() > (int) src.get_size().y)
69 src_rect.size.y = src.get_size().y - src_rect.pos.y;
71 if(dst_pos.x + src_rect.size.x > dst.get_size().x)
73 src_rect.size.x = dst.get_size().x - dst_pos.x;
75 if(dst_pos.y + src_rect.size.y > dst.get_size().y)
77 src_rect.size.y = dst.get_size().y - dst_pos.y;
79 blit_lower(src, src_rect, dst, dst_pos);
82 void Blitters::blit_lower_none(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
84 if(src_rect.pos == Point() && dst_pos == Point() && src.get_size().x == dst.get_size().x && src_rect.size.x == dst.get_size().x)
86 memcpy(dst.get_pixels(), src.get_pixels(), src_rect.size.x * src_rect.size.y * sizeof(Color));
90 const Color *src_line = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
91 Color *dst_line = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
92 for(unsigned int y = 0;y < src_rect.size.y;y++)
94 memcpy(dst_line, src_line, src_rect.size.x * sizeof(Color));
95 src_line += src.get_size().x;
96 dst_line += dst.get_size().x;
101 void Blitters::blit_lower_mask(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
103 const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
104 Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
105 for(unsigned int y = 0;y < src_rect.size.y;y++)
107 for(unsigned int x = 0;x < src_rect.size.x;x++)
111 *dst_pixel = *src_pixel;
116 src_pixel += src.get_size().x - src_rect.size.x;
117 dst_pixel += dst.get_size().x - src_rect.size.x;
121 void Blitters::blit_lower_alpha(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
123 const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
124 Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
125 for(unsigned int y = 0;y < src_rect.size.y;y++)
127 for(unsigned int x = 0;x < src_rect.size.x;x++)
129 dst_pixel->red += src_pixel->red * src_pixel->alpha - dst_pixel->red * src_pixel->alpha;
130 dst_pixel->green += src_pixel->green * src_pixel->alpha - dst_pixel->green * src_pixel->alpha;
131 dst_pixel->blue += src_pixel->blue * src_pixel->alpha - dst_pixel->green * src_pixel->blue;
135 src_pixel += src.get_size().x - src_rect.size.x;
136 dst_pixel += dst.get_size().x - src_rect.size.x;
140 void Blitters::blit_lower_add(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
142 const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
143 Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
144 for(unsigned int y = 0;y < src_rect.size.y;y++)
146 for(unsigned int x = 0;x < src_rect.size.x;x++)
148 if(src_pixel->red != 0 && dst_pixel->red != 0xff)
150 int redsum = dst_pixel->red + src_pixel->red * src_pixel->alpha / 0xff;
151 dst_pixel->red = redsum & ~0xff ? 0xff : redsum;
153 if(src_pixel->green != 0 && dst_pixel->green != 0xff)
155 int greensum = dst_pixel->green + src_pixel->green * src_pixel->alpha / 0xff;
156 dst_pixel->green = greensum & ~0xff ? 0xff : greensum;
158 if(src_pixel->blue != 0 && dst_pixel->blue != 0xff)
160 int bluesum = dst_pixel->blue + src_pixel->blue * src_pixel->alpha / 0xff;
161 dst_pixel->blue = bluesum & ~0xff ? 0xff : bluesum;
166 src_pixel += src.get_size().x - src_rect.size.x;
167 dst_pixel += dst.get_size().x - src_rect.size.x;
171 void Blitters::blit_lower_mod(const Surface &src, const Rect &src_rect, Surface &dst, const Point &dst_pos)
173 const Color *src_pixel = src.get_pixels() + src_rect.pos.y * src.get_size().x + src_rect.pos.x;
174 Color *dst_pixel = dst.get_pixels() + dst_pos.y * dst.get_size().x + dst_pos.x;
175 for(unsigned int y = 0;y < src_rect.size.y;y++)
177 for(unsigned int x = 0;x < src_rect.size.x;x++)
179 dst_pixel->red = dst_pixel->red * src_pixel->red / 0xff;
180 dst_pixel->green = dst_pixel->green * src_pixel->green / 0xff;
181 dst_pixel->blue = dst_pixel->blue * src_pixel->blue / 0xff;
182 dst_pixel->alpha = dst_pixel->alpha * src_pixel->alpha / 0xff;
186 src_pixel += src.get_size().x - src_rect.size.x;
187 dst_pixel += dst.get_size().x - src_rect.size.x;