Ветеран
Сообщения: 1180
Благодарности: 279
|
Профиль
|
Отправить PM
| Цитировать
Если не прибегать к библиотекам сторонних производителей, например gdi32.dll от микрософт, не пользоваться алгоритмами стандартной библиотеки c++, то код будет выглядеть примерно так:
Код: 
typedef int surf_bit_t;
struct rect_t
{
int left, top, right, bottom;
}
struct surface_desc
{
surf_bit_t *begin; // начало данных
unsigned width, height, stride; // длина, ширина блока, длина строчки
};
void __blt(surface_desc* from, surface_desc* to)
{
// копирование без проверки исходых данных.
// чтобы случайно не попортить память при записи, руководствуемся размерами конечной области
for(surf_bit_t *row_first1=to->begin,
*row_last1=to->begin+from->stride*to->width,
*row_first2=from->from->begin;
row_first1<row_last1; row_first1+=to->stride, row_first2+=from->stride)
{
// закомментирован пример кода для копирования,
// можешь поиграться с ним (переделать в закрашивание)
// for(unsigned col=0; col<to->width; ++col)
// {
// row_first1[col] = row_first2[col];
// }
memcpy(row_first2, row_first1, to->width*sizeof(surf_bit_t));
}
}
inline int __constraint(int x, int min, int max)
{
return x < min ? min : (x < max ? x : max);
}
void blt(surface_desc* from, int x, int y, int width, int height, surface_desc* to, int to_x, int to_y)
{
// более удобный для пользователя интерфейс
// с проверкой исходных данных
// вычисляем перекрывающийся прямоугольник для копирования.
surface_desc from1, to1;
{
// пересечение прямоугольника {0, 0, width, height} с
// исходным изображением, в координатах копируемого окошка
rect_t rect_src = {
__constraint(-x, 0, width),
__constraint(-y, 0, height),
__constraint(from->width - x, 0, width),
__constraint(from->height - y, 0, height)},
// пересечение {0, 0, width, height} с
// конечным изображением и сразу с пересечённым исходным rect_src
rect_dest = {
__constraint(__constraint(-x_to, 0, width), rect_src.left, rect_src.right),
__constraint(__constraint(-y_to, 0, height), rect_src.top, rect_src.bottom),
__constraint(__constraint(to->width - x_to, 0, width), rect_src.left, rect_src.right),
__constraint(__constraint(to->height - y_to, 0, height), rect_src.top, rect_src.bottom)};
// составляем полётное задание для __blt
from1.begin = from->begin + (rect_dest.top + y)*from->stride + rect_dest.left + x;
from1.stride = from->stride;
from1.width = rect_desc.right - rect_dest.left;
from1.height = rect_desc.bottom - rect_dest.top;
to1.begin = to->begin + (rect_dest.top + to_y)*from->stride + rect_dest.left + to_x;
to1.stride = to->stride;
to1.width = rect_desc.right - rect_dest.left;
to1.height = rect_desc.bottom - rect_dest.top;
}
__blt(&from1, &to1);
}
...
// как пользоваться
surf_bit_t screen1_bits[320*200];
surface_desc screen1 = {&screen1_bits, 320, 200, 320};
surf_bit_t screen2_bits[50*100];
surface_desc screen2 = {&screen2_bits, 50, 100, 50};
...
blt(&screen1, 100, 100, 60, 60, &screen2, 10, 10);
если внутри __blt заменить memcpy на memset, то получится "закрашивание". Рекомендую почитать в сторону функции BitBlt от винды. Если surf_bit_t - 8 битный, то можно сделать 8-битные картинки в памяти и смело пользоваться функциями GDI
|