ultimatepp/uppdev/AggCtrl/AggCtrlX11.cpp
cxl 2e4b276e07 Merge continued
git-svn-id: svn://ultimatepp.org/upp/trunk@10263 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2016-10-04 08:34:39 +00:00

258 lines
11 KiB
C++

#include "AggCtrl.h"
#ifdef PLATFORM_X11
AggCtrl::AggCtrl(agg::pix_format_e format):
pixformat(format), bpp(0),
sysformat(agg::pix_format_undefined),
byte_order(LSBFirst),
flip_y(false),
cx(16),cy(16),
r_mask(Upp::Xvisual->red_mask), g_mask(Upp::Xvisual->green_mask), b_mask(Upp::Xvisual->blue_mask)
{
ASSERT_(!(Upp::Xdepth<15||r_mask==0||g_mask==0||b_mask==0),"AGG requires at least 15-bit color depth and True- or DirectColor class.");
// Determine bpp from pixel format
switch(pixformat){
default: break;
case agg::pix_format_gray8:
bpp = 8; break;
case agg::pix_format_rgb565:
case agg::pix_format_rgb555:
bpp = 16; break;
case agg::pix_format_rgb24:
case agg::pix_format_bgr24:
bpp = 24; break;
case agg::pix_format_bgra32:
case agg::pix_format_abgr32:
case agg::pix_format_argb32:
case agg::pix_format_rgba32:
bpp = 32; break;
}
// Pre-determine the byte order
int t = 1;
int hw_byte_order = LSBFirst;
if (*(char*)&t == 0) hw_byte_order = MSBFirst;
// Perceive system pixel format by mask
switch (Upp::Xdepth) {
case 15:
sysbpp=16;
if (r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F) {
sysformat = agg::pix_format_rgb555;
byte_order = hw_byte_order;
}
break;
case 16:
sysbpp=16;
if (r_mask==0xF800&&g_mask==0x7E0&&b_mask==0x1F) {
sysformat = agg::pix_format_rgb565;
byte_order = hw_byte_order;
}
break;
case 24:
case 32:
sysbpp=32;
if (g_mask==0xFF00){
if (r_mask==0xFF&&b_mask==0xFF0000) {
switch(pixformat) {
case agg::pix_format_rgba32:
sysformat = agg::pix_format_rgba32;
byte_order = LSBFirst;
break;
case agg::pix_format_abgr32:
sysformat = agg::pix_format_abgr32;
byte_order = MSBFirst;
break;
default:
byte_order = hw_byte_order;
sysformat = (hw_byte_order==LSBFirst)?agg::pix_format_rgba32:agg::pix_format_abgr32;
break;
}
}
if (r_mask == 0xFF0000 && b_mask == 0xFF) {
switch (pixformat) {
case agg::pix_format_argb32:
sysformat = agg::pix_format_argb32;
byte_order = MSBFirst;
break;
case agg::pix_format_bgra32:
sysformat = agg::pix_format_bgra32;
byte_order = LSBFirst;
break;
default:
byte_order = hw_byte_order;
sysformat = (hw_byte_order == MSBFirst)?agg::pix_format_argb32:agg::pix_format_bgra32;
break;
}
}
}
break;
}
ASSERT_(sysformat!=agg::pix_format_undefined,"RGB masks are not compatible with AGG pixel formats");
// Allocate buffer
buf=new unsigned char[cx*cy*(bpp/8)];
// Connect rendering buffer
rbuf.attach(buf,cx,cy,(flip_y?-1:1)*cx*(bpp/8));
// Initialize XImage for sending the data to the X server
ximg=XCreateImage(Upp::Xdisplay,Upp::Xvisual,Upp::Xdepth,ZPixmap,0,(char*)buf,cx,cy,sysbpp,cx*(sysbpp/8));
ximg->byte_order = byte_order;
// User initialization
onInit();
};
void AggCtrl::PaintAgg(Upp::Draw& dest){PaintAgg(&rbuf,dest);};
void AggCtrl::PaintAgg(const agg::rendering_buffer* src,Upp::Draw& dest){
if(ximg==0) return;
ximg->data=(char*)(flip_y?(src->row_ptr(src->height())-1):src->row_ptr(0));
if(pixformat==sysformat){
XPutImage(Upp::Xdisplay,dest.GetDrawable(),dest.GetGC(),ximg,0,0,GetRect().left,GetRect().top,cx,cy);
XFlush(Upp::Xdisplay);
XSync(Upp::Xdisplay,false);
}else{
// Conversion to pixel format compatible with current system
int row_len = cx*sysbpp/8;
unsigned char* buf_tmp = new unsigned char[row_len*cy];
agg::rendering_buffer rbuf_tmp;
rbuf_tmp.attach(buf_tmp,cx,cy,flip_y?-row_len:row_len);
switch (sysformat){
default: break;
case agg::pix_format_rgb555:
switch (pixformat) {
default: break;
case agg::pix_format_rgb555:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb555_to_rgb555());break;
case agg::pix_format_rgb565:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb565_to_rgb555());break;
case agg::pix_format_rgb24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb24_to_rgb555());break;
case agg::pix_format_bgr24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgr24_to_rgb555());break;
case agg::pix_format_rgba32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgba32_to_rgb555());break;
case agg::pix_format_argb32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_argb32_to_rgb555());break;
case agg::pix_format_bgra32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgra32_to_rgb555());break;
case agg::pix_format_abgr32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_abgr32_to_rgb555());break;
}
break;
case agg::pix_format_rgb565:
switch (pixformat) {
default: break;
case agg::pix_format_rgb555:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb555_to_rgb565());break;
case agg::pix_format_rgb565:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb565_to_rgb565());break;
case agg::pix_format_rgb24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb24_to_rgb565());break;
case agg::pix_format_bgr24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgr24_to_rgb565());break;
case agg::pix_format_rgba32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgba32_to_rgb565());break;
case agg::pix_format_argb32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_argb32_to_rgb565());break;
case agg::pix_format_bgra32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgra32_to_rgb565());break;
case agg::pix_format_abgr32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_abgr32_to_rgb565());break;
}
break;
case agg::pix_format_rgba32:
switch (pixformat) {
default: break;
case agg::pix_format_rgb555:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb555_to_rgba32());break;
case agg::pix_format_rgb565:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb565_to_rgba32());break;
case agg::pix_format_rgb24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb24_to_rgba32());break;
case agg::pix_format_bgr24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgr24_to_rgba32());break;
case agg::pix_format_rgba32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgba32_to_rgba32());break;
case agg::pix_format_argb32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_argb32_to_rgba32());break;
case agg::pix_format_bgra32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgra32_to_rgba32());break;
case agg::pix_format_abgr32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_abgr32_to_rgba32());break;
}
break;
case agg::pix_format_abgr32:
switch (pixformat) {
default: break;
case agg::pix_format_rgb555:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb555_to_abgr32());break;
case agg::pix_format_rgb565:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb565_to_abgr32());break;
case agg::pix_format_rgb24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb24_to_abgr32());break;
case agg::pix_format_bgr24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgr24_to_abgr32());break;
case agg::pix_format_abgr32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_abgr32_to_abgr32());break;
case agg::pix_format_rgba32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgba32_to_abgr32());break;
case agg::pix_format_argb32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_argb32_to_abgr32());break;
case agg::pix_format_bgra32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgra32_to_abgr32());break;
}
break;
case agg::pix_format_argb32:
switch (pixformat) {
default: break;
case agg::pix_format_rgb555:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb555_to_argb32());break;
case agg::pix_format_rgb565:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb565_to_argb32());break;
case agg::pix_format_rgb24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb24_to_argb32());break;
case agg::pix_format_bgr24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgr24_to_argb32());break;
case agg::pix_format_rgba32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgba32_to_argb32());break;
case agg::pix_format_argb32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_argb32_to_argb32());break;
case agg::pix_format_abgr32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_abgr32_to_argb32());break;
case agg::pix_format_bgra32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgra32_to_argb32());break;
}
break;
case agg::pix_format_bgra32:
switch (pixformat) {
default: break;
case agg::pix_format_rgb555:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb555_to_bgra32());break;
case agg::pix_format_rgb565:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb565_to_bgra32());break;
case agg::pix_format_rgb24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgb24_to_bgra32());break;
case agg::pix_format_bgr24:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgr24_to_bgra32());break;
case agg::pix_format_rgba32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_rgba32_to_bgra32());break;
case agg::pix_format_argb32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_argb32_to_bgra32());break;
case agg::pix_format_abgr32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_abgr32_to_bgra32());break;
case agg::pix_format_bgra32:agg::color_conv(&rbuf_tmp, src, agg::color_conv_bgra32_to_bgra32());break;
}
break;
}
ximg->data=(char*)buf_tmp;
XPutImage(Upp::Xdisplay,dest.GetDrawable(),dest.GetGC(),ximg,0,0,GetRect().left,GetRect().top,cx,cy);
XFlush(Upp::Xdisplay);
XSync(Upp::Xdisplay,false);
delete [] buf_tmp;
}
};
void AggCtrl::Resized(){
// Update the dimensions, reallocate the buffer with new size, get a bigger XImage
cx=GetSize().cx;cy=GetSize().cy;
delete [] buf;
ximg->data = 0;
XDestroyImage(ximg);
buf=new unsigned char[cx*cy*(bpp/8)];
rbuf.attach(buf,cx,cy,(flip_y?-1:1)*cx*(bpp/8));
ximg=XCreateImage(Upp::Xdisplay,Upp::Xvisual,Upp::Xdepth,ZPixmap,0,(char*)buf,cx,cy,sysbpp,cx*(sysbpp/8));
ximg->byte_order=byte_order;
// User resize code
onResize(cx,cy);
};
AggCtrl::~AggCtrl() {
delete [] buf;
ximg->data = 0;
XDestroyImage(ximg);
};
void AggCtrl::Paint(Upp::Draw& draw) {
// Check if the control was resized
if(cx!=GetSize().cx||cy!=GetSize().cy){Resized();}
// User Drawing code
onDraw(draw);
// Draw to screen
PaintAgg(draw);
};
void AggCtrl::SetPixFmt(agg::pix_format_e format){
pixformat=format;
switch(format){
default: break;
case agg::pix_format_gray8:
bpp = 8; break;
case agg::pix_format_rgb565:
case agg::pix_format_rgb555:
bpp = 16; break;
case agg::pix_format_rgb24:
case agg::pix_format_bgr24:
bpp = 24; break;
case agg::pix_format_bgra32:
case agg::pix_format_abgr32:
case agg::pix_format_argb32:
case agg::pix_format_rgba32:
bpp = 32; break;
}
Resized();
};
void AggCtrl::onDraw(Upp::Draw& dest){};
void AggCtrl::onInit(){};
void AggCtrl::onResize(int width,int height){};
#endif