📄 agg_win32_bmp.cpp
字号:
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
// Contact: mcseemagg@yahoo.com
//----------------------------------------------------------------------------
//
// class pixel_map
//
//----------------------------------------------------------------------------
#include "agg_win32_bmp.h"
#include "agg_basics.h"
namespace agg
{
//------------------------------------------------------------------------
pixel_map::~pixel_map()
{
destroy();
}
//------------------------------------------------------------------------
pixel_map::pixel_map() :
m_bmp(0),
m_buf(0),
m_bpp(0),
m_is_internal(false),
m_img_size(0),
m_full_size(0)
{
}
//------------------------------------------------------------------------
void pixel_map::destroy()
{
if(m_bmp && m_is_internal) delete [] (unsigned char*)m_bmp;
m_bmp = 0;
m_is_internal = false;
m_buf = 0;
}
//------------------------------------------------------------------------
void pixel_map::create(unsigned width,
unsigned height,
org_e org,
unsigned clear_val)
{
destroy();
if(width == 0) width = 1;
if(height == 0) height = 1;
m_bpp = org;
create_from_bmp(create_bitmap_info(width, height, m_bpp));
create_gray_scale_palette(m_bmp);
m_is_internal = true;
if(clear_val <= 255)
{
memset(m_buf, clear_val, m_img_size);
}
}
//------------------------------------------------------------------------
HBITMAP pixel_map::create_dib_section(HDC h_dc,
unsigned width,
unsigned height,
org_e org,
unsigned clear_val)
{
destroy();
if(width == 0) width = 1;
if(height == 0) height = 1;
m_bpp = org;
HBITMAP h_bitmap = create_dib_section_from_args(h_dc, width, height, m_bpp);
create_gray_scale_palette(m_bmp);
m_is_internal = true;
if(clear_val <= 255)
{
memset(m_buf, clear_val, m_img_size);
}
return h_bitmap;
}
//------------------------------------------------------------------------
void pixel_map::clear(unsigned clear_val)
{
if(m_buf) memset(m_buf, clear_val, m_img_size);
}
//------------------------------------------------------------------------
void pixel_map::attach_to_bmp(BITMAPINFO *bmp)
{
if(bmp)
{
destroy();
create_from_bmp(bmp);
m_is_internal = false;
}
}
//static
//------------------------------------------------------------------------
unsigned pixel_map::calc_full_size(BITMAPINFO *bmp)
{
if(bmp == 0) return 0;
return sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * calc_palette_size(bmp) +
bmp->bmiHeader.biSizeImage;
}
//static
//------------------------------------------------------------------------
unsigned pixel_map::calc_header_size(BITMAPINFO *bmp)
{
if(bmp == 0) return 0;
return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp);
}
//static
//------------------------------------------------------------------------
unsigned pixel_map::calc_palette_size(unsigned clr_used, unsigned bits_per_pixel)
{
int palette_size = 0;
if(bits_per_pixel <= 8)
{
palette_size = clr_used;
if(palette_size == 0)
{
palette_size = 1 << bits_per_pixel;
}
}
return palette_size;
}
//static
//------------------------------------------------------------------------
unsigned pixel_map::calc_palette_size(BITMAPINFO *bmp)
{
if(bmp == 0) return 0;
return calc_palette_size(bmp->bmiHeader.biClrUsed, bmp->bmiHeader.biBitCount);
}
//static
//------------------------------------------------------------------------
unsigned char * pixel_map::calc_img_ptr(BITMAPINFO *bmp)
{
if(bmp == 0) return 0;
return ((unsigned char*)bmp) + calc_header_size(bmp);
}
//static
//------------------------------------------------------------------------
BITMAPINFO* pixel_map::create_bitmap_info(unsigned width,
unsigned height,
unsigned bits_per_pixel)
{
unsigned line_len = calc_row_len(width, bits_per_pixel);
unsigned img_size = line_len * height;
unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD);
unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size + img_size;
BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size];
bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp->bmiHeader.biWidth = width;
bmp->bmiHeader.biHeight = height;
bmp->bmiHeader.biPlanes = 1;
bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel;
bmp->bmiHeader.biCompression = 0;
bmp->bmiHeader.biSizeImage = img_size;
bmp->bmiHeader.biXPelsPerMeter = 0;
bmp->bmiHeader.biYPelsPerMeter = 0;
bmp->bmiHeader.biClrUsed = 0;
bmp->bmiHeader.biClrImportant = 0;
return bmp;
}
//static
//------------------------------------------------------------------------
void pixel_map::create_gray_scale_palette(BITMAPINFO *bmp)
{
if(bmp == 0) return;
unsigned rgb_size = calc_palette_size(bmp);
RGBQUAD *rgb = (RGBQUAD*)(((unsigned char*)bmp) + sizeof(BITMAPINFOHEADER));
unsigned brightness;
unsigned i;
for(i = 0; i < rgb_size; i++)
{
brightness = (255 * i) / (rgb_size - 1);
rgb->rgbBlue =
rgb->rgbGreen =
rgb->rgbRed = (unsigned char)brightness;
rgb->rgbReserved = 0;
rgb++;
}
}
//static
//------------------------------------------------------------------------
unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel)
{
unsigned n = width;
unsigned k;
switch(bits_per_pixel)
{
case 1: k = n;
n = n >> 3;
if(k & 7) n++;
break;
case 4: k = n;
n = n >> 1;
if(k & 3) n++;
break;
case 8:
break;
case 16: n *= 2;
break;
case 24: n *= 3;
break;
case 32: n *= 4;
break;
case 48: n *= 6;
break;
case 64: n *= 8;
break;
default: n = 0;
break;
}
return ((n + 3) >> 2) << 2;
}
//------------------------------------------------------------------------
void pixel_map::draw(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const
{
if(m_bmp == 0 || m_buf == 0) return;
unsigned bmp_x = 0;
unsigned bmp_y = 0;
unsigned bmp_width = m_bmp->bmiHeader.biWidth;
unsigned bmp_height = m_bmp->bmiHeader.biHeight;
unsigned dvc_x = 0;
unsigned dvc_y = 0;
unsigned dvc_width = m_bmp->bmiHeader.biWidth;
unsigned dvc_height = m_bmp->bmiHeader.biHeight;
if(bmp_rect)
{
bmp_x = bmp_rect->left;
bmp_y = bmp_rect->top;
bmp_width = bmp_rect->right - bmp_rect->left;
bmp_height = bmp_rect->bottom - bmp_rect->top;
}
dvc_x = bmp_x;
dvc_y = bmp_y;
dvc_width = bmp_width;
dvc_height = bmp_height;
if(device_rect)
{
dvc_x = device_rect->left;
dvc_y = device_rect->top;
dvc_width = device_rect->right - device_rect->left;
dvc_height = device_rect->bottom - device_rect->top;
}
if(dvc_width != bmp_width || dvc_height != bmp_height)
{
::SetStretchBltMode(h_dc, COLORONCOLOR);
::StretchDIBits(
h_dc, // handle of device context
dvc_x, // x-coordinate of upper-left corner of source rect.
dvc_y, // y-coordinate of upper-left corner of source rect.
dvc_width, // width of source rectangle
dvc_height, // height of source rectangle
bmp_x,
bmp_y, // x, y -coordinates of upper-left corner of dest. rect.
bmp_width, // width of destination rectangle
bmp_height, // height of destination rectangle
m_buf, // address of bitmap bits
m_bmp, // address of bitmap data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -