123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // Flexlay - A Generic 2D Game Editor
- // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- #include <assert.h>
- #include <iostream>
- #include <ClanLib/Display/pixel_format.h>
- #include <ClanLib/Display/palette.h>
- #include "blitter.hpp"
- void
- blit_opaque(CL_PixelBuffer target, CL_PixelBuffer brush, int x_pos, int y_pos)
- {
- assert(target.get_format().get_type() == pixelformat_rgba);
- assert(target.get_format().get_depth() == 32);
- target.lock();
- brush.lock();
- int start_x = std::max(0, -x_pos);
- int start_y = std::max(0, -y_pos);
- int end_x = std::min(brush.get_width(), target.get_width() - x_pos);
- int end_y = std::min(brush.get_height(), target.get_height() - y_pos);
- unsigned char* target_buf = static_cast<unsigned char*>(target.get_data());
- unsigned char* brush_buf = static_cast<unsigned char*>(brush.get_data());
- int target_pitch = target.get_pitch();
- int brush_pitch = brush.get_pitch();
- if (brush.get_format().get_type() == pixelformat_rgba)
- {
- if (brush.get_format().get_depth() == 32)
- {
- for (int y = start_y; y < end_y; ++y)
- for (int x = start_x; x < end_x; ++x)
- {
- int target_pos = (y + y_pos) * target_pitch + 4*(x + x_pos);
- int brush_pos = y * brush_pitch + x*4;
- target_buf[target_pos + 0] = brush_buf[brush_pos + 0];
- target_buf[target_pos + 1] = brush_buf[brush_pos + 1];
- target_buf[target_pos + 2] = brush_buf[brush_pos + 2];
- target_buf[target_pos + 3] = brush_buf[brush_pos + 3];
- }
- }
- else if (brush.get_format().get_depth() == 24)
- {
- for (int y = start_y; y < end_y; ++y)
- for (int x = start_x; x < end_x; ++x)
- {
- int target_pos = (y + y_pos) * target_pitch + 4*(x + x_pos);
- int brush_pos = y * brush_pitch + 3*x;
- target_buf[target_pos + 0] = 255;
- target_buf[target_pos + 1] = brush_buf[brush_pos + 0];
- target_buf[target_pos + 2] = brush_buf[brush_pos + 1];
- target_buf[target_pos + 3] = brush_buf[brush_pos + 2];
- }
- }
- else
- {
- std::cout << "Unsupported bpp: " << brush.get_format().get_depth() << std::endl;
- }
- }
- else if (brush.get_format().get_type() == pixelformat_index)
- {
- CL_Palette palette = brush.get_palette();
- for (int y = start_y; y < end_y; ++y)
- for (int x = start_x; x < end_x; ++x)
- {
- int target_pos = (y + y_pos) * target_pitch + 4*(x + x_pos);
- int brush_pos = y * brush_pitch + x;
- target_buf[target_pos + 0] = 255;
- target_buf[target_pos + 1] = palette.colors[brush_buf[brush_pos]].get_blue();
- target_buf[target_pos + 2] = palette.colors[brush_buf[brush_pos]].get_green();
- target_buf[target_pos + 3] = palette.colors[brush_buf[brush_pos]].get_red();
- }
- }
- else
- {
- assert(!"Unknown pixelformat type");
- }
- brush.unlock();
- target.unlock();
- }
- void
- blit(CL_PixelBuffer target, CL_PixelBuffer brush, int x_pos, int y_pos)
- {
- target.lock();
- brush.lock();
- int start_x = std::max(0, -x_pos);
- int start_y = std::max(0, -y_pos);
- int end_x = std::min(brush.get_width(), target.get_width() - x_pos);
- int end_y = std::min(brush.get_height(), target.get_height() - y_pos);
- unsigned char* target_buf = static_cast<unsigned char*>(target.get_data());
- unsigned char* brush_buf = static_cast<unsigned char*>(brush.get_data());
- // FIXME: This doesn't take pitch into account
- int target_width = target.get_width();
- int brush_width = brush.get_width();
- if (brush.get_format().get_type() == pixelformat_rgba)
- {
- if (brush.get_format().get_depth() == 32)
- {
- for (int y = start_y; y < end_y; ++y)
- for (int x = start_x; x < end_x; ++x)
- {
- int target_pos = (y + y_pos) * target_width + x + x_pos;
- int brush_pos = y * brush_width + x;
- unsigned char a = brush_buf[4*brush_pos + 0];
- unsigned char r = brush_buf[4*brush_pos + 1];
- unsigned char g = brush_buf[4*brush_pos + 2];
- unsigned char b = brush_buf[4*brush_pos + 3];
- unsigned char ta = target_buf[4*target_pos + 0];
- unsigned char tr = target_buf[4*target_pos + 1];
- unsigned char tg = target_buf[4*target_pos + 2];
- unsigned char tb = target_buf[4*target_pos + 3];
- float alpha = a/255.0f;
- target_buf[4*target_pos + 0] = std::min(255, ta + a);
- target_buf[4*target_pos + 1] = std::min(255, int((1-alpha)*tr + alpha*r));
- target_buf[4*target_pos + 2] = std::min(255, int((1-alpha)*tg + alpha*g));
- target_buf[4*target_pos + 3] = std::min(255, int((1-alpha)*tb + alpha*b));
- }
- }
- else if (brush.get_format().get_depth() == 24)
- {
- for (int y = start_y; y < end_y; ++y)
- for (int x = start_x; x < end_x; ++x)
- {
- int target_pos = (y + y_pos) * target_width + x + x_pos;
- int brush_pos = y * brush_width + x;
- target_buf[4*target_pos + 0] = 255;
- target_buf[4*target_pos + 1] = brush_buf[3*brush_pos + 0];
- target_buf[4*target_pos + 2] = brush_buf[3*brush_pos + 1];
- target_buf[4*target_pos + 3] = brush_buf[3*brush_pos + 2];
- }
- }
- else
- {
- std::cout << "Unsupported bpp: " << brush.get_format().get_depth() << std::endl;
- }
- }
- else if (brush.get_format().get_type() == pixelformat_index)
- {
- CL_Palette palette = brush.get_palette();
- for (int y = start_y; y < end_y; ++y)
- for (int x = start_x; x < end_x; ++x)
- {
- int target_pos = (y + y_pos) * target_width + x + x_pos;
- int brush_pos = y * brush_width + x;
- target_buf[4*target_pos + 0] = 255;
- target_buf[4*target_pos + 1] = palette.colors[brush_buf[brush_pos]].get_blue();
- target_buf[4*target_pos + 2] = palette.colors[brush_buf[brush_pos]].get_green();
- target_buf[4*target_pos + 3] = palette.colors[brush_buf[brush_pos]].get_red();
- }
- }
- else
- {
- assert(!"Unknown pixelformat type");
- }
- brush.unlock();
- target.unlock();
- }
- void clear(CL_PixelBuffer canvas)
- {
- unsigned char* buffer;
- canvas.lock();
- buffer = static_cast<unsigned char*>(canvas.get_data());
- memset(buffer, 0, sizeof(unsigned char) * canvas.get_pitch() * canvas.get_height());
- canvas.unlock();
- }
- /* EOF */
|