enhance gui.gdoverlay(), the new one can overlay a part of image and load indexed image.
This commit is contained in:
parent
4fbf560d7a
commit
e91edccdbb
|
@ -3195,17 +3195,21 @@ DEFINE_LUA_FUNCTION(gui_gdscreenshot, "[whichScreen='both']")
|
|||
|
||||
// draws a gd image that's in gdstr format to the screen
|
||||
// example: gui.gdoverlay(gd.createFromPng("myimage.png"):gdStr())
|
||||
DEFINE_LUA_FUNCTION(gui_gdoverlay, "[x=0,y=0,]gdimage[,alphamul]")
|
||||
DEFINE_LUA_FUNCTION(gui_gdoverlay, "[dx=0,dy=0,]gdimage[,sx=0,sy=0,width,height][,alphamul]")
|
||||
{
|
||||
int xStart = 0;
|
||||
int yStart = 0;
|
||||
int xStartDst = 0;
|
||||
int yStartDst = 0;
|
||||
int xStartSrc = 0;
|
||||
int yStartSrc = 0;
|
||||
int width, height;
|
||||
int numArgs = lua_gettop(L);
|
||||
|
||||
int index = 1;
|
||||
if(lua_type(L,index) == LUA_TNUMBER)
|
||||
{
|
||||
xStart = lua_tointeger(L,index++);
|
||||
xStartDst = lua_tointeger(L,index++);
|
||||
if(lua_type(L,index) == LUA_TNUMBER)
|
||||
yStart = lua_tointeger(L,index++);
|
||||
yStartDst = lua_tointeger(L,index++);
|
||||
}
|
||||
|
||||
luaL_checktype(L,index,LUA_TSTRING); // have to check for errors before deferring
|
||||
|
@ -3215,18 +3219,13 @@ DEFINE_LUA_FUNCTION(gui_gdoverlay, "[x=0,y=0,]gdimage[,alphamul]")
|
|||
|
||||
const unsigned char* ptr = (const unsigned char*)lua_tostring(L,index++);
|
||||
|
||||
// GD format header for truecolor image (11 bytes)
|
||||
ptr++;
|
||||
bool trueColor = (*ptr++ == 254);
|
||||
if (!trueColor) {
|
||||
luaL_error(L, "indexed images are not supported");
|
||||
return 0;
|
||||
const bool defSrcRect = ((numArgs - index + 1) < 2);
|
||||
if (!defSrcRect) {
|
||||
xStartSrc = luaL_checkinteger(L, index++);
|
||||
yStartSrc = luaL_checkinteger(L, index++);
|
||||
width = luaL_checkinteger(L, index++);
|
||||
height = luaL_checkinteger(L, index++);
|
||||
}
|
||||
int width = *ptr++ << 8;
|
||||
width |= *ptr++;
|
||||
int height = *ptr++ << 8;
|
||||
height |= *ptr++;
|
||||
ptr += 5;
|
||||
|
||||
LuaContextInfo& info = GetCurrentInfo();
|
||||
int alphaMul = info.transparencyModifier;
|
||||
|
@ -3235,16 +3234,6 @@ DEFINE_LUA_FUNCTION(gui_gdoverlay, "[x=0,y=0,]gdimage[,alphamul]")
|
|||
if(alphaMul <= 0)
|
||||
return 0;
|
||||
|
||||
prepare_drawing();
|
||||
u8* Dst = (u8*)curGuiData.data;
|
||||
gui_adjust_coord(xStart,yStart);
|
||||
|
||||
int xMin = curGuiData.xMin;
|
||||
int yMin = curGuiData.yMin;
|
||||
int xMax = curGuiData.xMax - 1;
|
||||
int yMax = curGuiData.yMax - 1;
|
||||
int strideBytes = curGuiData.stridePix * 4;
|
||||
|
||||
// since there aren't that many possible opacity levels,
|
||||
// do the opacity modification calculations beforehand instead of per pixel
|
||||
int opacMap[256];
|
||||
|
@ -3259,24 +3248,96 @@ DEFINE_LUA_FUNCTION(gui_gdoverlay, "[x=0,y=0,]gdimage[,alphamul]")
|
|||
for(int i = 128; i < 256; i++)
|
||||
opacMap[i] = 0; // what should we do for them, actually?
|
||||
|
||||
Dst += yStart * strideBytes;
|
||||
for(int y = yStart; y < height+yStart && y < yMax; y++, Dst += strideBytes)
|
||||
// GD format header for truecolor image (11 bytes)
|
||||
ptr++;
|
||||
bool trueColor = (*ptr++ == 254);
|
||||
int gdWidth = *ptr++ << 8;
|
||||
gdWidth |= *ptr++;
|
||||
int gdHeight = *ptr++ << 8;
|
||||
gdHeight |= *ptr++;
|
||||
int bytespp = (trueColor ? 4 : 1);
|
||||
if (defSrcRect) {
|
||||
width = gdWidth;
|
||||
height = gdHeight;
|
||||
}
|
||||
|
||||
if ((!trueColor && *ptr) || (trueColor && !*ptr)) {
|
||||
luaL_error(L, "gdoverlay: inconsistent color type.");
|
||||
return 0;
|
||||
}
|
||||
ptr++;
|
||||
int colorsTotal = 0;
|
||||
if (!trueColor) {
|
||||
colorsTotal = *ptr++ << 8;
|
||||
colorsTotal |= *ptr++;
|
||||
}
|
||||
int transparent = *ptr++ << 24;
|
||||
transparent |= *ptr++ << 16;
|
||||
transparent |= *ptr++ << 8;
|
||||
transparent |= *ptr++;
|
||||
struct { int r, g, b, a; } pal[256];
|
||||
if (!trueColor) for (int i = 0; i < 256; i++) {
|
||||
pal[i].r = *ptr++;
|
||||
pal[i].g = *ptr++;
|
||||
pal[i].b = *ptr++;
|
||||
pal[i].a = opacMap[*ptr++];
|
||||
}
|
||||
|
||||
prepare_drawing();
|
||||
u8* Dst = (u8*)curGuiData.data;
|
||||
gui_adjust_coord(xStartDst,yStartDst);
|
||||
|
||||
int xMin = curGuiData.xMin;
|
||||
int yMin = curGuiData.yMin;
|
||||
int xMax = curGuiData.xMax - 1;
|
||||
int yMax = curGuiData.yMax - 1;
|
||||
int strideBytes = curGuiData.stridePix * 4;
|
||||
|
||||
// limit source rect
|
||||
if (xStartSrc < 0) {
|
||||
width += xStartSrc;
|
||||
xStartDst -= xStartSrc;
|
||||
xStartSrc = 0;
|
||||
}
|
||||
if (yStartSrc < 0) {
|
||||
height += yStartSrc;
|
||||
yStartDst -= yStartSrc;
|
||||
yStartSrc = 0;
|
||||
}
|
||||
if (xStartSrc + width >= gdWidth)
|
||||
width = gdWidth - xStartSrc;
|
||||
if (yStartSrc+height >= gdHeight)
|
||||
height = gdHeight - yStartSrc;
|
||||
if (width <= 0 || height <= 0)
|
||||
return 0;
|
||||
ptr += (yStartSrc * gdWidth + xStartSrc) * bytespp;
|
||||
|
||||
Dst += yStartDst * strideBytes;
|
||||
for(int y = yStartDst; y < height+yStartDst && y < yMax; y++, Dst += strideBytes)
|
||||
{
|
||||
if(y < yMin)
|
||||
ptr += width * 4;
|
||||
ptr += gdWidth * bytespp;
|
||||
else
|
||||
{
|
||||
int xA = (xStart < xMin ? xMin : xStart);
|
||||
int xB = (xStart+width > xMax ? xMax : xStart+width);
|
||||
ptr += (xA - xStart) * 4;
|
||||
int xA = (xStartDst < xMin ? xMin : xStartDst);
|
||||
int xB = (xStartDst+width > xMax ? xMax : xStartDst+width);
|
||||
ptr += (xA - xStartDst) * bytespp;
|
||||
for(int x = xA; x < xB; x++)
|
||||
{
|
||||
int opac = opacMap[ptr[0]];
|
||||
u32 pix = (opac|(ptr[3]<<8)|(ptr[2]<<16)|(ptr[1]<<24));
|
||||
blend32((u32*)(Dst+x*4), pix);
|
||||
ptr += 4;
|
||||
if (trueColor) {
|
||||
int opac = opacMap[ptr[0]];
|
||||
u32 pix = (opac|(ptr[3]<<8)|(ptr[2]<<16)|(ptr[1]<<24));
|
||||
blend32((u32*)(Dst+x*4), pix);
|
||||
ptr += 4;
|
||||
}
|
||||
else {
|
||||
int palNo = ptr[0];
|
||||
u32 pix = (pal[palNo].a|(pal[palNo].b<<8)|(pal[palNo].g<<16)|(pal[palNo].r<<24));
|
||||
blend32((u32*)(Dst+x*4), pix);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
ptr += (xStart+width - xB) * 4;
|
||||
ptr += (gdWidth - (xB - xStartDst)) * bytespp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue