Files
Webcam/include/modules/script_squirrel/legacy/picture_binding.cpp

516 lines
16 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "binding_helpers.h"
#include "ui/ui.h"
#include "font/font_renderer.h"
#include "picture/pict_io.h"
using namespace GS;
using namespace GS::Script;
void IterateTextParameters(HSQUIRRELVM vm, int idx, TextState &state);
//------------------------------------------------------------------------------
SQInteger NewPicture(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETINT(w)
__SQ_GETINT(h)
__SQ_GETEND
Picture *p = new Picture;
if (!p || !p->AllocAs(w, h))
return sq_throwerror(vm, String::Format("Failed to allocate a new %dx%d picture.", w, h));
__SQ_RETURNSAFEPTR(p, typetag_Picture)
}
SQInteger LoadPicture(HSQUIRRELVM vm)
{
__SQ_GETSTART(1)
__SQ_GETSTRING(path)
Picture *p = new Picture;
if (!p)
return sq_throwerror(vm, "Failed to allocate picture.");
if (!PictureIO::Get().Load(*p, path))
return sq_throwerror(vm, String::Format("Failed to load picture '%s'.", path));
__SQ_GETEND
__SQ_RETURNSAFEPTR(p, typetag_Picture)
}
SQInteger PictureClone(HSQUIRRELVM vm)
{
__SQ_GETSINGLESAFEPTR(p, Picture, typetag_Picture)
__SQ_RETURNSAFEPTR(new Picture(*p), typetag_Picture);
}
//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
SQInteger PictureWriteText(HSQUIRRELVM vm)
{
__SQ_GETSTART(5)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETRECT(out_rect)
__SQ_GETSTRING(text)
__SQ_GETSAFEPTR(font, FontEx, typetag_Font)
TextState state;
IterateTextParameters(vm, -1, state);
__SQ_GETUPDATESTACK
state.font = font;
iRect clip_rect = p->GetRect();
FontRenderer::Format(text, state, out_rect);
FontRenderer::Compose(*p, text, state, out_rect, clip_rect);
__SQ_GETEND
__SQ_RETURN
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
SQInteger PictureApplyConvolution(HSQUIRRELVM vm)
{
Picture *pic;
if (!CObject::Get(vm, -6, (void **)&pic, typetag_Picture))
return -1;
if (!pic)
return sq_throwerror(vm, "Invalid picture.");
// Kernel size.
SQInteger kw, kh;
sq_getinteger(vm, -5, &kw);
sq_getinteger(vm, -4, &kh);
int kernel[1024];
if ((kw * kh) > 1024)
return sq_throwerror(vm, "The convolution kernel is exceeding 1024 entries.");
sq_pushnull(vm); // iterator
for (int n = 0; n < (kw * kh); ++n)
{
if (SQ_FAILED(sq_next(vm, -4)))
break;
// Here -1 is the value and -2 is the key.
SQInteger v;
sq_getinteger(vm, -1, &v);
kernel[n] = v;
sq_pop(vm, 2); // Pops key and val before the next iteration.
}
sq_pop(vm, 1); // Pop the iterator.
SQFloat weight;
sq_getfloat(vm, -2, &weight);
SQInteger pass;
sq_getinteger(vm, -1, &pass);
sq_pop(vm, 4); // Pop function arguments.
if (!pic->ApplyConvolution(kw, kh, kernel, int(weight * 256), pass))
return sq_throwerror(vm, "Convolution filter failed.");
return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
SQInteger PictureLine(HSQUIRRELVM vm)
{
__SQ_GETSTART(6)
__SQ_GETSAFEPTR(pic, Picture, typetag_Picture)
__SQ_GETFLOAT(sx)
__SQ_GETFLOAT(sy)
__SQ_GETFLOAT(ex)
__SQ_GETFLOAT(ey)
__SQ_GETVECTORW(c)
__SQ_GETEND
fRect rect = pic->GetRect().AsFloat();
rect.ex -= 2; rect.ey -= 2;
if ((rect.ex <= rect.sx) || (rect.ey < rect.sy))
return 0;
pic->DrawLineHQ(sx, sy, ex, ey, c.x, c.y, c.z, c.w, &rect);
return 0;
}
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger PictureLoadContent(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSAFEPTR(pic, Picture, typetag_Picture)
__SQ_GETSTRING(path)
bool r = PictureIO::Get().Load(*pic, path);
__SQ_GETEND
__SQ_RETURNBOOL(r)
}
SQInteger PictureSaveTGA(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETSTRING(path)
if (!PictureIO::Get().TgaSave(*p, path))
return sq_throwerror(vm, String::Format("Failed to save picture to '%s'", path));
__SQ_GETEND
__SQ_RETURN
}
SQInteger PictureSaveJPG(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETSTRING(path)
p->Convert(PixelFormat::RGB8);
if (!PictureIO::Get().Save(*p, path, "IJG"))
return sq_throwerror(vm, String::Format("Failed to save picture to '%s'", path));
__SQ_GETEND
__SQ_RETURN
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger PictureGetRect(HSQUIRRELVM vm)
{
__SQ_GETSINGLESAFEPTR(p, Picture, typetag_Picture)
iRect rect(0, 0, 0, 0);
if (p) rect.Set(0, 0, p->GetWidth(), p->GetHeight());
__SQ_RETURNRECT(rect)
}
SQInteger PictureAlloc(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETINT(w)
__SQ_GETINT(h)
__SQ_GETEND
if (!p->AllocAs(w, h))
return sq_throwerror(vm, "Failed to allocate picture buffer");
__SQ_RETURN
}
SQInteger PictureResize(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETINT(w)
__SQ_GETINT(h)
__SQ_GETEND
p->Resize(w, h);
__SQ_RETURN
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SQInteger PictureSetPixel(HSQUIRRELVM vm)
{
__SQ_GETSTART(4)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETFLOAT(x)
__SQ_GETFLOAT(y)
__SQ_GETVECTORW(c)
__SQ_GETEND
p->DrawPlot(x, y, c.x, c.y, c.z, c.w);
__SQ_RETURN
}
SQInteger PictureGetPixel(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETFLOAT(x)
__SQ_GETFLOAT(y)
__SQ_GETEND
Color c;
p->Sample(x / p->GetWidth(), y / p->GetHeight(), c);
__SQ_RETURNVECTORW(Vector4(c.x, c.y, c.z, c.w))
}
SQInteger PictureFlip(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETBOOL(h)
__SQ_GETBOOL(v)
__SQ_GETEND
p->Flip(asbool(h), asbool(v));
__SQ_RETURN
}
SQInteger PictureFillLockAlpha(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETVECTORW(c)
__SQ_GETEND
p->Fill(c.x, c.y, c.z, c.w, 0, true);
__SQ_RETURN
}
SQInteger PictureFill(HSQUIRRELVM vm)
{
__SQ_GETSTART(2)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETVECTORW(c)
__SQ_GETEND
p->Fill(c.x, c.y, c.z, c.w);
__SQ_RETURN
}
SQInteger PictureFillRect(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
__SQ_GETVECTORW(c)
__SQ_GETRECT(clip_rect)
__SQ_GETEND
p->Fill(c.x, c.y, c.z, c.w, &clip_rect);
__SQ_RETURN
}
SQInteger PictureBlitRect(HSQUIRRELVM vm)
{
__SQ_GETSTART(5)
__SQ_GETSAFEPTR(src, Picture, typetag_Picture)
__SQ_GETSAFEPTR(dst, Picture, typetag_Picture)
__SQ_GETRECT(src_rect)
__SQ_GETRECT(dst_rect)
__SQ_GETINT(blend_mode)
__SQ_GETEND
Picture::Blit(*src, *dst, &src_rect, &dst_rect, (Picture::BlendMode)blend_mode);
__SQ_RETURN
}
SQInteger PictureBlitRectMasked(HSQUIRRELVM vm)
{
__SQ_GETSTART(5)
__SQ_GETSAFEPTR(src, Picture, typetag_Picture)
__SQ_GETSAFEPTR(dst, Picture, typetag_Picture)
__SQ_GETSAFEPTR(msk, Picture, typetag_Picture)
__SQ_GETRECT(src_rect)
__SQ_GETRECT(dst_rect)
__SQ_GETEND
Picture::BlitMask(*src, *dst, *msk, &src_rect, &dst_rect);
__SQ_RETURN
}
SQInteger PictureBlit(HSQUIRRELVM vm)
{
__SQ_GETSTART(3)
__SQ_GETSAFEPTR(src, Picture, typetag_Picture)
__SQ_GETSAFEPTR(dst, Picture, typetag_Picture)
__SQ_GETINT(blend_mode)
__SQ_GETEND
Picture::Blit(*src, *dst, 0, 0, (Picture::BlendMode)blend_mode);
__SQ_RETURN
}
//------------------------------------------------------------------------------
//--------------------------------------------------------
void RegisterPictureBinding(HSQUIRRELVM vm)
//--------------------------------------------------------
{
/*#
Topic: Picture
Type: Picture
#*/
/*#
Section: PictureManagement
Desc: Management
#*/
/*#
Func: NewPicture
Proto: Picture:int width,int height
Desc: Create a new picture, width and height are specified in pixels.
Example: local picture = NewPicture()
#*/
sq_register(vm, NewPicture, "NewPicture", _SC(".nn"));
/*#
Func: LoadPicture
Proto: Picture:string path
Desc: Load a picture. This function supports the following formats: Jpeg, Bmp, Targa, Png, Gif and PSD with alpha channel.
Note: No caching mechanism involved, every call to this function will result in a filesystem access.
Example: local picture = LoadPicture("assets/picture.png")
#*/
sq_register(vm, LoadPicture, "LoadPicture", _SC(".s"));
/*#
Func: PictureClone
Proto: Picture:Picture source
Desc: Clone a picture, return the cloned picture.
#*/
sq_register(vm, PictureClone, "PictureClone", _SC(".x"));
/*#
Section: PictureDrawing
Desc: Drawing
#*/
/*#
Func: PictureAlloc
Proto: bool:Picture,width,height
Desc: Change the picture internal storage dimensions, existing data will be lost.
#*/
sq_register(vm, PictureAlloc, "PictureAlloc", _SC(".xnn"));
/*#
Func: PictureLoadContent
Proto: bool:Picture,string path
Desc: Reload a picture object content from file.
See: LoadPicture
#*/
sq_register(vm, PictureLoadContent, "PictureLoadContent", _SC(".xs"));
/*#
Func: PictureSaveTGA
Proto: void:Picture,string path
Desc: Save a picture object to Targa.
Note: Make sure that you have access to the filesystem you plan on writing to.
See: SystemHasMountPoint
#*/
sq_register(vm, PictureSaveTGA, "PictureSaveTGA", _SC(".xs"));
/*#
Func: PictureSaveJPG
Proto: void:Picture,string path
Desc: Save a picture object to jpg.
Note: Make sure that you have access to the filesystem you plan on writing to.
See: SystemHasMountPoint
#*/
sq_register(vm, PictureSaveJPG, "PictureSaveJPG", _SC(".xs"));
/*#
Func: PictureGetRect
Proto: Rect:Picture
Desc: Return a picture bounding rectangle.
Example:
local pict = PictureLoad("picture.psd")
local rect = PictureGetRect(pict)
print("Picture width = " + rect.GetWidth() + ", height = " + rect.GetHeight())
#*/
sq_register(vm, PictureGetRect, "PictureGetRect", _SC(".x"));
/*#
Func: PictureFill
Proto: void:Picture,Vector rgba
Desc: Fill a picture with a solid color defined as an RGBA vector.
#*/
sq_register(vm, PictureFill, "PictureFill", _SC(".xx"));
/*#
Func: PictureFillLockAlpha
Proto: void:Picture,Vector rgba
Desc: Fill a picture with a solid color defined from an RGBA vector, does not write to alpha.
#*/
sq_register(vm, PictureFillLockAlpha, "PictureFillLockAlpha", _SC(".xx"));
/*#
Func: PictureFillRect
Proto: void:Picture,Vector rgba,Rect
Desc: Fill a rectangle inside a picture with a solid color defined from an RGBA vector.
#*/
sq_register(vm, PictureFillRect, "PictureFillRect", _SC(".xxx"));
/*#
Func: PictureApplyConvolution
Proto: void:Picture,int kernel_width,int kernel_height,array kernel_values,float filter_weight,int pass_count
Desc: Apply a convolution filter to the picture using a user specified kernel of values.<br>
<br>
The <em>weight</em> and <em>pass</em> parameters will be 1 in most use case,
kernel values are integer in the nominal range [0;255].
Example:
function BlurPicture(picture, blur_strength = 1, blur_pass_count = 1)
{
local kernel = // 7x7 kernel
[
0, 1, 2, 4, 2, 1, 0,
1, 2, 4, 6, 4, 2, 1,
2, 3, 5, 8, 5, 3, 2,
2, 4, 8, 8, 8, 4, 2,
2, 3, 5, 8, 5, 3, 2,
1, 2, 4, 6, 4, 2, 1,
0, 1, 2, 4, 2, 1, 0
]
PictureApplyConvolution(picture, 7, 7, kernel, blur_strength, blur_pass_count)
}
#*/
sq_register(vm, PictureApplyConvolution, "PictureApplyConvolution", _SC(".xiiani"));
/*#
Func: PictureLine
Proto: bool:Texture,float start_x,float start_y,float end_x,float end_y,Vector rgba
Desc: Draw a line, color is specified as an RGBA vector.
#*/
sq_register(vm, PictureLine, "PictureLine", _SC(".xnnnnx"));
/*#
Func: PictureWriteFont
Proto: void:Picture,rect,string text,Font font,TextState
Desc: Render formatted text to a picture.<br>
TextState is table containing the following keys:<br>
<ul>
<li><b>'size'</b>: Size in pixels.
<li><b>'color'</b>: Hexadecimal RGBA (eg. 0xff0000ff for red at 100% opacity).
<li><b>'align'</b>: Text alignment, can be any of "left", "center", "right" or "justify".
<li><b>'format'</b>: Text formating, can be any of "standard", "paragraph" or "column".
<li><b>'tracking'</b>: Integer value specifying an extra space between glyphs.
<li><b>'heading'</b>: Integer value specifying an extra space between lines.
</ul>
#*/
sq_register(vm, PictureWriteText, "PictureWriteFont", _SC(".xxsxt"));
sq_register(vm, PictureWriteText, "PictureWriteText", _SC(".xxsxt"));
/*#
Func: PictureSetPixel
Proto: void:Picture,float x,float y,Vector rgba
Desc: Set picture pixel at coordinate {x, y} in picture space from an RGBA vector.
#*/
sq_register(vm, PictureSetPixel, "PictureSetPixel", _SC(".xnnx"));
/*#
Func: PictureGetPixel
Proto: Vector:Picture,float x,float y
Desc: Return the picture pixel at coordinate {x, y} in picture space as an RGBA vector.
#*/
sq_register(vm, PictureGetPixel, "PictureGetPixel", _SC(".xnn"));
/*#
Section: PictureManipulation
Desc: Manipulation
#*/
/*#
Func: PictureResize
Proto: void:Picture,float w,float h
Desc: Resize picture.
#*/
sq_register(vm, PictureResize, "PictureResize", _SC(".xii"));
/*#
Func: PictureFlip
Proto: void:Picture,bool horizontal, bool vertical
Desc: Flip picture on one or both axis.
#*/
sq_register(vm, PictureFlip, "PictureFlip", _SC(".xbb"));
/*#
Section: PictureBlitting
Desc: Blitting
#*/
/*#
Func: PictureBlit
Proto: void:Picture source,Picture destination,BlendMode mode
Desc: Blit a picture to another picture with a selectable blend mode.
#*/
sq_register(vm, PictureBlit, "PictureBlit", _SC(".xxi"));
/*#
Func: PictureBlitRect
Proto: void:Picture source,Picture destination,Rect source,Rect destination,BlendMode mode
Desc: Blit a picture to another picture, both clipping zones and the blend mode can be specified.
#*/
sq_register(vm, PictureBlitRect, "PictureBlitRect", _SC(".xxxxi"));
/*#
Func: PictureBlitRectMasked
Proto: void:Picture source,Picture destination,Picture mask,Rect source,Rect destination
Desc: Blit a picture to another picture using a third picture alpha channel as an opacity mask.
#*/
sq_register(vm, PictureBlitRectMasked, "PictureBlitRectMasked", _SC(".xxxxx"));
sq_pushroottable(vm);
/*#
Enum: BlendMode
Values: BlendReplace,BlendAdd,BlendCompose,BlendComposeFast,BlendMultiply,BlendMultiply2x,BlendAlphaAdd,BlendAlphaMultiply,BlendAlphaMultiply2x,RgbToAlpha
#*/
sq_pushstring(vm, "BlendReplace", -1); sq_pushinteger(vm, Picture::BlendReplace); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendAdd", -1); sq_pushinteger(vm, Picture::BlendAdd); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendCompose", -1); sq_pushinteger(vm, Picture::BlendCompose); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendComposeFast", -1); sq_pushinteger(vm, Picture::BlendComposeFast); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendMultiply", -1); sq_pushinteger(vm, Picture::BlendMultiply); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendMultiply2x", -1); sq_pushinteger(vm, Picture::BlendMultiply2x); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendAlphaAdd", -1); sq_pushinteger(vm, Picture::BlendAlphaAdd); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendAlphaMultiply", -1); sq_pushinteger(vm, Picture::BlendAlphaMultiply); sq_newslot(vm, -3, true);
sq_pushstring(vm, "BlendAlphaMultiply2x", -1); sq_pushinteger(vm, Picture::BlendAlphaMultiply2x); sq_newslot(vm, -3, true);
sq_pushstring(vm, "RgbToAlpha", -1); sq_pushinteger(vm, Picture::RgbToAlpha); sq_newslot(vm, -3, true);
sq_pop(vm, 1);
}