diff options
Diffstat (limited to 'Src/Wasabi/api/imgldr')
21 files changed, 1626 insertions, 0 deletions
diff --git a/Src/Wasabi/api/imgldr/ImgLoaderEnum.h b/Src/Wasabi/api/imgldr/ImgLoaderEnum.h new file mode 100644 index 00000000..e71f4c4d --- /dev/null +++ b/Src/Wasabi/api/imgldr/ImgLoaderEnum.h @@ -0,0 +1,24 @@ +#ifndef __WASABI_IMGLOADERENUM_H +#define __WASABI_IMGLOADERENUM_H + +#include <api/service/svc_enum.h> +#include <bfc/string/StringW.h> + +class ImgLoaderEnum : public SvcEnumT<svc_imageLoader> { +public: + ImgLoaderEnum(uint8_t *data, int datalen) : mem(datalen, data) { } + ImgLoaderEnum(const wchar_t *filename) : fname(filename) { } + +protected: + virtual int testService(svc_imageLoader *svc) + { + if (!fname.isempty() && !svc->isMine(fname)) return 0; + return svc->testData(mem, mem.getSizeInBytes()); + } + +private: + StringW fname; + MemBlock<uint8_t> mem; +}; + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/imgldr/api_imgldr.cpp b/Src/Wasabi/api/imgldr/api_imgldr.cpp new file mode 100644 index 00000000..20d03bcf --- /dev/null +++ b/Src/Wasabi/api/imgldr/api_imgldr.cpp @@ -0,0 +1,20 @@ +#include <precomp.h> +#include "api_imgldr.h" + +#ifdef CBCLASS +#undef CBCLASS +#endif +#define CBCLASS imgldr_apiI +START_DISPATCH; + CB(IMGLDR_API_MAKEBMP, imgldr_makeBmp); +#ifdef _WIN32 + CB(IMGLDR_API_MAKEBMP2, imgldr_makeBmp2); +#endif + VCB(IMGLDR_API_RELEASEBMP, imgldr_releaseBmp); +#ifdef WASABI_COMPILE_SKIN + CB(IMGLDR_API_REQUESTSKINBITMAP, imgldr_requestSkinBitmap); + CB(IMGLDR_API_REQUESTSKINREGION, imgldr_requestSkinRegion); + VCB(IMGLDR_API_CACHESKINREGION, imgldr_cacheSkinRegion); + VCB(IMGLDR_API_RELEASESKINBITMAP, imgldr_releaseSkinBitmap); +#endif //WASABI_COMPILE_SKIN +END_DISPATCH; diff --git a/Src/Wasabi/api/imgldr/api_imgldr.h b/Src/Wasabi/api/imgldr/api_imgldr.h new file mode 100644 index 00000000..55e19bec --- /dev/null +++ b/Src/Wasabi/api/imgldr/api_imgldr.h @@ -0,0 +1,98 @@ +#ifndef __API_IMGLOADER_H +#define __API_IMGLOADER_H + +#include <wasabicfg.h> +#include <bfc/dispatch.h> + +class RegionServer; +class api_region; + +class imgldr_api : public Dispatchable +{ +public: + ARGB32 *imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h); + ARGB32 *imgldr_makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup = NULL); + void imgldr_releaseBmp(ARGB32 *bmpbits); + ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached); + RegionServer *imgldr_requestSkinRegion(const wchar_t *id); + void imgldr_cacheSkinRegion(const wchar_t *id, api_region *r); + void imgldr_releaseSkinBitmap(ARGB32 *bmpbits); + + DISPATCH_CODES + { + IMGLDR_API_MAKEBMP = 0, + IMGLDR_API_MAKEBMP2 = 10, + IMGLDR_API_RELEASEBMP = 20, + IMGLDR_API_REQUESTSKINBITMAP = 30, + IMGLDR_API_REQUESTSKINREGION = 40, + IMGLDR_API_CACHESKINREGION = 50, + IMGLDR_API_RELEASESKINBITMAP = 60, + }; +}; + +inline ARGB32 *imgldr_api::imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h) +{ + return _call(IMGLDR_API_MAKEBMP, (ARGB32 *)NULL, filename, has_alpha, w, h); +} + +inline ARGB32 *imgldr_api::imgldr_makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup) +{ + return _call(IMGLDR_API_MAKEBMP2, (ARGB32 *)NULL, hInst, id, has_alpha, w, h, colorgroup); +} + +inline void imgldr_api::imgldr_releaseBmp(ARGB32 *bmpbits) +{ + _voidcall(IMGLDR_API_RELEASEBMP, bmpbits); +} + +#ifdef WASABI_COMPILE_SKIN + +inline ARGB32 *imgldr_api::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) +{ + return _call(IMGLDR_API_REQUESTSKINBITMAP, (ARGB32 *)NULL, file, has_alpha, x, y, subw, subh, w, h, cached); +} + +inline RegionServer *imgldr_api::imgldr_requestSkinRegion(const wchar_t *id) +{ + return _call(IMGLDR_API_REQUESTSKINREGION, (RegionServer *)NULL, id); +} + +inline void imgldr_api::imgldr_cacheSkinRegion(const wchar_t *id, api_region *r) +{ + _voidcall(IMGLDR_API_CACHESKINREGION, id, r); +} + +inline void imgldr_api::imgldr_releaseSkinBitmap(ARGB32 *bmpbits) +{ + _voidcall(IMGLDR_API_RELEASESKINBITMAP, bmpbits); +} + +#endif //WASABI_COMPILE_SKIN + +class imgldr_apiI : public imgldr_api +{ +public: + virtual ARGB32 *imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h) = 0; +#ifdef _WIN32 + virtual ARGB32 *imgldr_makeBmp2(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup = NULL) = 0; +#endif + virtual void imgldr_releaseBmp(ARGB32 *bmpbits) = 0; +#ifdef WASABI_COMPILE_SKIN + virtual ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) = 0; + virtual RegionServer *imgldr_requestSkinRegion(const wchar_t *id) = 0; + virtual void imgldr_cacheSkinRegion(const wchar_t *id, api_region *r) = 0; + virtual void imgldr_releaseSkinBitmap(ARGB32 *bmpbits) = 0; +#endif //WASABI_COMPILE_SKIN + +protected: + RECVS_DISPATCH; +}; + +// {703ECC7C-B3D8-4e1e-B8B5-A7563D9D6F30} +static const GUID imgLdrApiServiceGuid = + { 0x703ecc7c, 0xb3d8, 0x4e1e, { 0xb8, 0xb5, 0xa7, 0x56, 0x3d, 0x9d, 0x6f, 0x30 } }; + +extern imgldr_api *imgLoaderApi; + + +#endif diff --git a/Src/Wasabi/api/imgldr/imggen/grad.cpp b/Src/Wasabi/api/imgldr/imggen/grad.cpp new file mode 100644 index 00000000..acec2eab --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/grad.cpp @@ -0,0 +1,60 @@ +#include "precomp.h" + +#include "grad.h" + +#include <api/xml/xmlparams.h> +#include <api/memmgr/api_memmgr.h> +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(GradientGen_Svc); +DECLARE_SERVICETSINGLE(svc_imageGenerator, GradientImage); +END_SERVICES(GradientGen_Svc, _GradientGen_Svc); + +#ifdef _X86_ +extern "C" { int _link_GradientGen_Svc; } +#else +extern "C" { int __link_GradientGen_Svc; } +#endif + +#endif + + +int GradientImage::testDesc(const wchar_t *desc) { + return !_wcsicmp(desc, L"$gradient"); +} + +ARGB32 *GradientImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params) +{ + int _w = params->getItemValueInt(L"w",1); + if (_w == 0) _w = 1; + int _h = params->getItemValueInt(L"h",1); + if (_h == 0) _h = 1; + if (_w <= 0 || _h <= 0) return NULL; + +#ifdef WASABI_COMPILE_MEMMGR + ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32)); +#else + ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32)); +#endif + + setX1((float)WTOF(params->getItemValue(L"gradient_x1"))); + setY1((float)WTOF(params->getItemValue(L"gradient_y1"))); + setX2((float)WTOF(params->getItemValue(L"gradient_x2"))); + setY2((float)WTOF(params->getItemValue(L"gradient_y2"))); + + setPoints(params->getItemValue(L"points")); + + setMode(params->getItemValue(L"mode")); + + setReverseColors(TRUE); // cuz we're imggen + + setAntialias(params->getItemValueInt(L"antialias")); + + renderGradient(ret, _w, _h); + + *w = _w; + *h = _h; + *has_alpha = 1; // will be optimized anyway + + return ret; +} diff --git a/Src/Wasabi/api/imgldr/imggen/grad.h b/Src/Wasabi/api/imgldr/imggen/grad.h new file mode 100644 index 00000000..8ee4c886 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/grad.h @@ -0,0 +1,15 @@ +#ifndef _GRAD_H +#define _GRAD_H + +#include <api/service/svcs/svc_imggen.h> +#include <bfc/draw/gradient.h> + +class GradientImage : public svc_imageGeneratorI, public Gradient +{ +public: + static const char *getServiceName() { return "Gradient image generator"; } + virtual int testDesc(const wchar_t *desc); + virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params=NULL); +}; + +#endif diff --git a/Src/Wasabi/api/imgldr/imggen/imggen.cpp b/Src/Wasabi/api/imgldr/imggen/imggen.cpp new file mode 100644 index 00000000..bcf0b6d4 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/imggen.cpp @@ -0,0 +1,29 @@ +#include "precomp.h" +#include "imggen.h" + +#include "solid.h" +#include "grad.h" +#include "osedge.h" +#include "poly.h" +#include "shadowwnd.h" + +#include "../studio/services/servicei.h" + +static WACNAME wac; +WAComponentClient *the = &wac; + +// {9C9CB15E-2904-4df2-B8CE-FFBC6CD230DC} +static const GUID guid = +{ 0x9c9cb15e, 0x2904, 0x4df2, { 0xb8, 0xce, 0xff, 0xbc, 0x6c, 0xd2, 0x30, 0xdc } }; + +WACNAME::WACNAME() { + registerService(new waServiceFactoryTSingle<svc_imageGenerator, SolidImage>); + registerService(new waServiceFactoryTSingle<svc_imageGenerator, GradientImage>); + registerService(new waServiceFactoryTSingle<svc_imageGenerator, OsEdgeImage>); + registerService(new waServiceFactoryTSingle<svc_imageGenerator, PolyImage>); + registerService(new XuiObjectCreator<XuiShadowWndSvc>); +} + +GUID WACNAME::getGUID() { + return guid; +} diff --git a/Src/Wasabi/api/imgldr/imggen/imggen.h b/Src/Wasabi/api/imgldr/imggen/imggen.h new file mode 100644 index 00000000..9af473d5 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/imggen.h @@ -0,0 +1,14 @@ +#ifndef _IMGGEN_H +#define _IMGGEN_H + +#include "../studio/wac.h" + +#define WACNAME WACimggen +class WACNAME : public WAComponentClient { +public: + WACNAME(); + + virtual const char *getName() { return "Standard Image Generators"; }; + virtual GUID getGUID(); +}; +#endif diff --git a/Src/Wasabi/api/imgldr/imggen/osedge.cpp b/Src/Wasabi/api/imgldr/imggen/osedge.cpp new file mode 100644 index 00000000..c699a860 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/osedge.cpp @@ -0,0 +1,95 @@ +#include "precomp.h" + +#include "osedge.h" +#include <api/xml/xmlparams.h> +#include <bfc/parse/pathparse.h> +#include <api/memmgr/api_memmgr.h> +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(OsEdgeGen_Svc); +DECLARE_SERVICETSINGLE(svc_imageGenerator, OsEdgeImage); +END_SERVICES(OsEdgeGen_Svc, _OsEdgeGen_Svc); + +#ifdef _X86_ +extern "C" { int _link_OsEdgeGen_Svc; } +#else +extern "C" { int __link_OsEdgeGen_Svc; } +#endif + +#endif + + +int OsEdgeImage::testDesc(const wchar_t *desc) { + return !_wcsicmp(desc, L"$osedge"); +} + +ARGB32 *OsEdgeImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params) +{ + int _w = params->getItemValueInt(L"w", 1); + if (_w == 0) _w = 1; + int _h = params->getItemValueInt(L"h", 1); + if (_h == 0) _h = 1; + if (_w <= 0 || _h <= 0) return NULL; + +#ifdef WASABI_COMPILE_MEMMGR + ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32)); +#else + ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32)); +#endif + + RECT r = Wasabi::Std::makeRect(0, 0, _w, _h); + + BITMAPINFO bmi; + ZERO(bmi); + bmi.bmiHeader.biSize = sizeof(bmi); + bmi.bmiHeader.biWidth = _w; + bmi.bmiHeader.biHeight = -_h; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + // the rest are 0 + ARGB32 *bits; + HBITMAP hbmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + HDC hdc = CreateCompatibleDC(NULL); + HBITMAP prevbmp = (HBITMAP)SelectObject(hdc, hbmp); + + unsigned long edgev = 0; + if (!_wcsicmp(params->getItemValue(L"edge"), L"bump")) edgev = EDGE_BUMP; + else if (!_wcsicmp(params->getItemValue(L"edge"), L"etched")) edgev = EDGE_ETCHED; + else if (!_wcsicmp(params->getItemValue(L"edge"), L"raised")) edgev = EDGE_RAISED; + else if (!_wcsicmp(params->getItemValue(L"edge"), L"sunken")) edgev = EDGE_SUNKEN; + if (edgev == 0) edgev = EDGE_RAISED; + + unsigned long sides = 0; + PathParserW pp(params->getItemValue(L"sides"), L","); + for (int i = 0; i < pp.getNumStrings(); i++) { + const wchar_t *p = pp.enumString(i); + if (!_wcsicmp(p, L"left")) sides |= BF_LEFT; + if (!_wcsicmp(p, L"top")) sides |= BF_TOP; + if (!_wcsicmp(p, L"right")) sides |= BF_RIGHT; + if (!_wcsicmp(p, L"bottom")) sides |= BF_BOTTOM; + if (!_wcsicmp(p, L"all")) sides |= BF_RECT; + if (!_wcsicmp(p, L"middle")) sides |= BF_MIDDLE; + if (!_wcsicmp(p, L"flat")) sides |= BF_FLAT; + if (!_wcsicmp(p, L"soft")) sides |= BF_SOFT; + if (!_wcsicmp(p, L"mono")) sides |= BF_MONO; + } + +// DO EET + DrawEdge(hdc, &r, edgev, sides); + + MEMCPY(ret, bits, sizeof(ARGB32) * _w * _h); + for (int i = 0; i < _w * _h; i++) { // force alpha + ret[i] |= 0xff000000; + } + + SelectObject(hdc, prevbmp); + DeleteDC(hdc); + DeleteObject(hbmp); + + *w = _w; + *h = _h; + *has_alpha = 1; // will be optimized anyway + + return ret; +} diff --git a/Src/Wasabi/api/imgldr/imggen/osedge.h b/Src/Wasabi/api/imgldr/imggen/osedge.h new file mode 100644 index 00000000..f00771a1 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/osedge.h @@ -0,0 +1,13 @@ +#ifndef _OSEDGE_H +#define _OSEDGE_H + +#include <api/service/svcs/svc_imggen.h> + +class OsEdgeImage : public svc_imageGeneratorI { +public: + static const char *getServiceName() { return "OS Edge image generator"; } + virtual int testDesc(const wchar_t *desc); + virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params=NULL); +}; + +#endif diff --git a/Src/Wasabi/api/imgldr/imggen/poly.cpp b/Src/Wasabi/api/imgldr/imggen/poly.cpp new file mode 100644 index 00000000..086664e8 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/poly.cpp @@ -0,0 +1,59 @@ +#include "precomp.h" + +#include "poly.h" + +#include <api/xml/xmlparams.h> +#include <api/memmgr/api_memmgr.h> +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(PolyGen_Svc); +DECLARE_SERVICETSINGLE(svc_imageGenerator, PolyImage); +END_SERVICES(PolyGen_Svc, _PolyGen_Svc); + +#ifdef _X86_ +extern "C" { int _link_PolyGen_Svc; } +#else +extern "C" { int __link_PolyGen_Svc; } +#endif + +#endif + +int PolyImage::testDesc(const wchar_t *desc) { + return !_wcsicmp(desc, L"$polygon"); +} + +void premultiply(ARGB32 *m_pBits, int nwords); + +#include <bfc/draw/drawpoly.h> + +ARGB32 *PolyImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params) +{ + int _w = (params->getItemValueInt(L"w", 1)); + if (_w == 0) _w = 1; + int _h = (params->getItemValueInt(L"h", 1)); + if (_h == 0) _h = 1; + if (_w <= 0 || _h <= 0) return NULL; + + const wchar_t *bgcolorstr = params->getItemValue(L"bgcolor"); + ARGB32 bgcolor = (bgcolorstr == NULL || *bgcolorstr=='\0') ? 0 : _byteswap_ulong(WASABI_API_SKIN->parse(params->getItemValue(L"bgcolor"), L"color")<<8); + + unsigned int bgalpha = params->getItemValueInt(L"bgalpha", 0); + bgcolor |= ((bgalpha & 0xff) << 24); + + premultiply(&bgcolor, 1); + +#ifdef WASABI_COMPILE_MEMMGR + ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32)); +#else + ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32)); +#endif + + MEMFILL<ARGB32>(ret, bgcolor, _w * _h); + + Draw::drawPointList(ret, _w, _h, params->getItemValue(L"points")); + + *w = _w; + *h = _h; + *has_alpha = 1; + return ret; +} diff --git a/Src/Wasabi/api/imgldr/imggen/poly.h b/Src/Wasabi/api/imgldr/imggen/poly.h new file mode 100644 index 00000000..07095056 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/poly.h @@ -0,0 +1,13 @@ +#ifndef _POLY_H +#define _POLY_H + +#include <api/service/svcs/svc_imggen.h> + +class PolyImage : public svc_imageGeneratorI { +public: + static const char *getServiceName() { return "Polygon image generator"; } + virtual int testDesc(const wchar_t *desc); + virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params=NULL); +}; + +#endif diff --git a/Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp b/Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp new file mode 100644 index 00000000..fb61c95c --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/shadowwnd.cpp @@ -0,0 +1,152 @@ +#include "precomp.h" + +#include "shadowwnd.h" + +#include "../bfc/canvas.h" +#include "../bfc/region.h" + +enum { TARGET }; + +char XuiShadowWndParams[][]= +{ + "TARGET", +}; +XuiShadowWnd::XuiShadowWnd() { + myxuihandle = newXuiHandle(); + addParam(myxuihandle, XuiShadowWndParams[0], TARGET, XUI_ATTRIBUTE_REQUIRED); + group = NULL; + bltcanvas = NULL; + c_w = c_h = 0; + in_paint = 0; +} + +XuiShadowWnd::~XuiShadowWnd() { + delete bltcanvas; +} + +int XuiShadowWnd::onInit() { + XUISHADOWWND_PARENT::onInit(); + +DebugString("on iniiit"); + + attachToGroup(); +setTimer(10, 50); + + return 1; +} + +void XuiShadowWnd::timerclient_timerCallback(int id) { + if (id == 10) { + if (group == NULL) attachToGroup(); + delete bltcanvas; + RECT r; group->getClientRect(&r); + bltcanvas = new BltCanvas(r.right - r.left, r.bottom - r.top); + in_paint++; + group->paint(bltcanvas); +MEMFILL<ARGB32>((unsigned long *)bltcanvas->getBits(), 0xffffffff, (r.right - r.left) * 20); + in_paint--; + invalidate(); + } else + XUISHADOWWND_PARENT::timerclient_timerCallback(id); +} + +int XuiShadowWnd::onPaint(Canvas *canvas) { +#if 0 +if (group == NULL) attachToGroup(); +if (group == NULL) { DebugString("groupNull"); } +if (group == NULL) return 0; + +#endif +DebugString("begin painting"); + +if (in_paint++) { +// RECT cr = clientRect(); +// canvas->fillRect(&cr, RGB(255,0,255)); +//MEMFILL<ARGB32>((unsigned long *)canvas->getBits(), 0xffffffff, (cr.right - cr.left) * 20); +DebugString("filla!"); +} else { +#if 0 + RECT cr; + group->getClientRect(&cr); + SkinBitmap *bm +bltcanvas->blit(0, 0, +BltCanvas c(cr.right - cr.left, cr.bottom - cr.top); +group->paint(&c); +#if 0 +c.pushPen(0,255,0); +c.lineDraw(0, 0, cr.right, cr.bottom); +/c.popPen(); +#endif +MEMFILL<ARGB32>((unsigned long *)c.getBits(), 0xffffffff, (cr.right - cr.left) * 20); +c.blit(0, 0, canvas, 0, 0, cr.right - cr.left, cr.bottom - cr.top); + +DebugString("get from group!"); +#endif + if (bltcanvas != NULL) { + SkinBitmap *bm = bltcanvas->getSkinBitmap(); + bm->stretchToRectAlpha(canvas, &clientRect(), getPaintingAlpha()); +DebugString("bleet!"); + } +} +in_paint--; + return 1; +} + +int XuiShadowWnd::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) { + if (xuihandle != myxuihandle) + return XUISHADOWWND_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value); + switch (xmlattributeid) { + case TARGET: + targetname = value; +DebugString("set target %s", value); + if (isPostOnInit()) attachToGroup(); + break; + default: return 0; + } + return 1; +} + +void XuiShadowWnd::attachToGroup() { + if (targetname.isempty()) return; + group = findWindow(targetname); + if (group == NULL) return; + monitorWindow(group); +DebugString("attached to group rw %d", group); + + delete bltcanvas; bltcanvas = NULL; +} + +void XuiShadowWnd::onAfterPaint(PaintCallbackInfo *info) { +DebugString("after paint"); +#if 0 + RECT ncr; + group->getNonClientRect(&ncr); + c_w = ncr.right - ncr.left; + c_h = ncr.bottom - ncr.top; + +DebugString("w %d h %d", c_w, c_h); + + delete bltcanvas; bltcanvas = NULL; + if (c_w != 0 && c_h != 0) bltcanvas = new BltCanvas(c_w, c_h); + + Canvas *c = info->getCanvas(); + api_region *r = info->getRegion(); + // blit what changed + RegionI saved; + c->getClipRgn(&saved); + bltcanvas->selectClipRgn(r); + c->blit(0, 0, bltcanvas, 0, 0, c_w, c_h); + c->selectClipRgn(&saved); + + invalidate(); +#endif +} + +void XuiShadowWnd::onInvalidation(PaintCallbackInfo *info) { +// invalidate(); +DebugString("got invalidate"); +} + +void XuiShadowWnd::onWindowDeleted(api_window *w) { + if (w == group) group = NULL; +} diff --git a/Src/Wasabi/api/imgldr/imggen/shadowwnd.h b/Src/Wasabi/api/imgldr/imggen/shadowwnd.h new file mode 100644 index 00000000..8082dba5 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/shadowwnd.h @@ -0,0 +1,40 @@ +#ifndef _SHADOW_H +#define _SHADOW_H + +#include "../common/guiobjwnd.h" +#include "../bfc/paintcb.h" + +#define XUISHADOWWND_PARENT GuiObjectWnd +class XuiShadowWnd : public XUISHADOWWND_PARENT, public PaintCallback { +public: + static const wchar_t *xuiobject_getXmlTag() { return "Shadow"; } + static const char *xuiobject_getServiceName() { return "Shadow XuiObject"; } + + XuiShadowWnd(); + virtual ~XuiShadowWnd(); + + virtual int onInit(); + + virtual int onPaint(Canvas *canvas); + + virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value); + + virtual void onAfterPaint(PaintCallbackInfo *info); + virtual void onInvalidation(PaintCallbackInfo *info); +protected: + virtual void onWindowDeleted(BaseWnd *w); + void attachToGroup(); + virtual void timerclient_timerCallback(int id); + +private: + int myxuihandle; + StringW targetname; + api_window *group; + BltCanvas *bltcanvas; + int c_w, c_h; + int in_paint; +}; + +class XuiShadowWndSvc : public XuiObjectSvc2<XuiShadowWnd> {}; + +#endif diff --git a/Src/Wasabi/api/imgldr/imggen/solid.cpp b/Src/Wasabi/api/imgldr/imggen/solid.cpp new file mode 100644 index 00000000..7f461eaa --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/solid.cpp @@ -0,0 +1,67 @@ +#include "precomp.h" + +#include "solid.h" +#include <api/xml/xmlparams.h> +#include <api/memmgr/api_memmgr.h> + +#ifndef _WASABIRUNTIME + +BEGIN_SERVICES(SolidGen_Svc); +DECLARE_SERVICETSINGLE(svc_imageGenerator, SolidImage); +END_SERVICES(SolidGen_Svc, _SolidGen_Svc); + +#ifdef _X86_ +extern "C" { int _link_SolidGen_Svc; } +#else +extern "C" { int __link_SolidGen_Svc; } +#endif + +#endif + +int SolidImage::testDesc(const wchar_t *desc) +{ + return !WCSICMP(desc, L"$solid"); +} + +void premultiply(ARGB32 *m_pBits, int nwords) +{ + for (; nwords > 0; nwords--, m_pBits++) + { + unsigned __int8 *pixel = (unsigned __int8 *)m_pBits; + unsigned int alpha = pixel[3]; + if (alpha == 255) continue; + pixel[0] = (pixel[0] * alpha) >> 8; // blue + pixel[1] = (pixel[1] * alpha) >> 8; // green + pixel[2] = (pixel[2] * alpha) >> 8; // red + } +} + +ARGB32 *SolidImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params) +{ + int _w = params->getItemValueInt(L"w", 1); + if (_w == 0) _w = 1; + int _h = params->getItemValueInt(L"h", 1); + if (_h == 0) _h = 1; + if (_w <= 0 || _h <= 0) return NULL; + ARGB32 color = _byteswap_ulong(WASABI_API_SKIN->parse(params->getItemValue(L"color"), L"color") << 8); + + unsigned int alpha = params->getItemValueInt(L"alpha", 255); + color |= ((alpha & 0xff) << 24); + + premultiply(&color, 1); + +#ifdef WASABI_COMPILE_MEMMGR + ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32)); +#else + ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32)); +#endif + + MEMFILL<ARGB32>(ret, color, _w * _h); + + *w = _w; + *h = _h; + + *has_alpha = (alpha == 255) ? 0 : 1; + + return ret; +} diff --git a/Src/Wasabi/api/imgldr/imggen/solid.h b/Src/Wasabi/api/imgldr/imggen/solid.h new file mode 100644 index 00000000..d810bc1c --- /dev/null +++ b/Src/Wasabi/api/imgldr/imggen/solid.h @@ -0,0 +1,14 @@ +#ifndef _SOLID_H +#define _SOLID_H + +#include <api/service/svcs/svc_imggen.h> + +class SolidImage : public svc_imageGeneratorI +{ +public: + static const char *getServiceName() { return "Solid Color image generator"; } + virtual int testDesc(const wchar_t *desc); + virtual ARGB32 *genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params = NULL); +}; + +#endif diff --git a/Src/Wasabi/api/imgldr/imgldr.cpp b/Src/Wasabi/api/imgldr/imgldr.cpp new file mode 100644 index 00000000..d7e33b54 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imgldr.cpp @@ -0,0 +1,554 @@ +#include <precomp.h> +#include <setjmp.h> +#include <bfc/bfc_assert.h> +#include <api.h> + +#include <bfc/wasabi_std.h> +#include <tataki/bitmap/bitmap.h> +#include <api/skin/skinfilter.h> // ApplySkinFilters + +#include "imgldr.h" +#ifdef _WIN32 +#include <api/imgldr/winbmp.h> +#endif +#include <api/imgldr/skinbmps.h> + +#include <api/skin/skinparse.h> +#include <api/skin/skinelem.h> +#include <api/skin/gammamgr.h> + +#include <api/service/svcs/svc_skinfilter.h> +#include <api/service/svcs/svc_imgload.h> +#include <api/service/svcs/svc_imggen.h> +#include "ImgLoaderEnum.h" +#include <api/memmgr/api_memmgr.h> +#include <bfc/string/PathString.h> +#include <api/locales/localesmgr.h> + +//#define DEBUG_OUTPUT + +#define IMAGEHEADERLEN 256 + +#ifdef _WIN32 +ARGB32 *imageLoader::makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *forcegroup) +{ + ARGB32 *bits = makeBmp(StringPrintfW(L"res://%u,%i", hInst, id), NULL, has_alpha, w, h, NULL, TRUE, NULL); + if (bits && *w > 0 && *h > 0) + { + ApplySkinFilters::apply(StringPrintfW(L"resource:%x,%d", hInst, id), forcegroup, bits, *w, *h); + } + return bits; +} +#endif + +StringW imageLoader::getWallpaper() +{ + StringW ret(L""); +#ifdef WIN32 + HKEY hkey; + static wchar_t file[MAX_PATH]; + file[0] = 0; + if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"), &hkey) == ERROR_SUCCESS) + { + unsigned long len = MAX_PATH; + RegQueryValueExW(hkey, L"Wallpaper", 0, NULL, (unsigned char *)&file, &len); + RegCloseKey(hkey); + } + if (file[0] && GetFileAttributesW(file) != (DWORD) - 1) ret = file; +#endif + return ret; +} +extern StringW g_resourcepath; + +ARGB32 *imageLoader::makeBmp(const wchar_t *_filename, const wchar_t *path, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params, bool addMem, int *force_nocache) +{ + if (!_filename || !*_filename) + return 0; + + + ARGB32 *ret = NULL; + + if (has_alpha != NULL) + *has_alpha = 0; //BU + + // test image generator services FIRST + ImgGeneratorEnum ige(_filename); + svc_imageGenerator *gen; + while ((gen = ige.getNext()) != NULL) + { + ret = gen->genImage(_filename, has_alpha, w, h, params); + int cacheable = gen->outputCacheable(); + ige.release(gen); + if (ret != NULL) + { + ApplySkinFilters::apply(params->getItemValue(L"id"), params->getItemValue(L"gammagroup"), ret, *w, *h); + if (addMem) addMemUsage(_filename, (*w) * (*h) * sizeof(int)); + optimizeHasAlpha(ret, *w * *h, has_alpha); + // don't try to cache generated images + if (force_nocache) *force_nocache = !cacheable; + return ret; + } + } + + StringW wallpaper; + if (!WCSICMP(_filename, L"$wallpaper")) + { + wallpaper = getWallpaper(); + _filename = wallpaper.getValue(); + } + + MemBlock<uint8_t> mem; + + wchar_t olddir[PATH_MAX] = {0}; + Wasabi::Std::getCurDir(olddir, PATH_MAX); + Wasabi::Std::setCurDir(WASABI_API_APP->path_getAppPath()); + + StringW file; + + // benski> try language pack first + StringPathCombine skinLocalePath(LocalesManager::getLocaleRoot(), WASABI_API_SKIN->getSkinName()); + file.swap(StringPathCombine(skinLocalePath, _filename)); + OSFILETYPE in = WFOPEN(file, WF_READONLY_BINARY); + + if (in == OPEN_FAILED) + { + // try the language pack's folder itself before falling back to the resource path + file.swap(StringPathCombine(LocalesManager::getLocaleRoot(), _filename)); + in = WFOPEN(file, WF_READONLY_BINARY); + } + + if (in == OPEN_FAILED) + { + if (path) + { + file.swap(StringPathCombine(path, _filename)); + in = WFOPEN(file, WF_READONLY_BINARY); + } + else + in = WFOPEN(file=_filename, WF_READONLY_BINARY); + } + +#ifdef WASABI_COMPILE_SKIN + if (in == OPEN_FAILED) + { + file.swap(StringPathCombine(WASABI_API_SKIN->getSkinPath(), _filename)); + in = WFOPEN(file, WF_READONLY_BINARY); + } + +#if 0 // this isn't used in gen_ff, basically makes it look in C:/Program Files/Winamp/Skins/Default/ + if (in == OPEN_FAILED) + { + file.swap(StringPathCombine(Skin::getDefaultSkinPath(), _filename)); + in = WFOPEN(file, WF_READONLY_BINARY); + } +#endif + + // look in the fallback stuff (in Winamp5, this is c:/program files/winamp/plugins/freeform/xml) + if (in == OPEN_FAILED) + { + file.swap(StringPathCombine(g_resourcepath, _filename)); + in = WFOPEN(file, WF_READONLY_BINARY); + } +#endif + + if (in == OPEN_FAILED && path) + { + in = WFOPEN(file = _filename, WF_READONLY_BINARY); + } + + Wasabi::Std::setCurDir(olddir); + + if (in != OPEN_FAILED) + { + int filelen = (int)FGETSIZE(in); + if (filelen > 0) + { + mem.setSize(filelen); + int len = FREAD(mem, 1, mem.getSizeInBytes(), in); + if (len == filelen) + { + svc_imageLoader *loader = ImgLoaderEnum(mem, len).getNext(); + if (loader != NULL) + { + ret = loader->loadImage(mem, mem.getSizeInBytes(), w, h, params); + if (ret != NULL) + { + if (addMem) + addMemUsage(file, (*w) * (*h) * sizeof(ARGB32)); + optimizeHasAlpha(ret, *w * *h, has_alpha); + } + SvcEnum::release(loader); + } + } + } // filelen > 0 + FCLOSE(in); + } // if file opened + if (ret != NULL) + { + return ret; + } + else if (in != OPEN_FAILED && mem) + { + int m = getFileType(mem); +#ifdef WIN32 + switch (m) + { + case FT_BMP: + { + wchar_t tmpname[WA_MAX_PATH] = L""; + + // FG> if loading bmp from disk, no need to do the copy to disk + HBITMAP hbmp = (HBITMAP)LoadImageW(0, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); + + if (!hbmp) + { + // CT> extract/copy the file into temp directory (so we don't have any trouble if the file + // is in a ZIP file). this whole copying thing will go away as soon as we'll get rid of + // the LoadImage win32 function and use our own bmp loading functions + + GetTempPathW(WA_MAX_PATH, tmpname); + wcscat(tmpname, L"wa3tmp"); + OSFILETYPE fs = WFOPEN(file, WF_READONLY_BINARY); + if (fs != OPEN_FAILED) + { + OSFILETYPE fd = WFOPEN(tmpname, L"wb"); + int l; + do + { + char buf[1024] = {0}; + l = FREAD(buf, 1, sizeof(buf), fs); + if (l > 0) FWRITE(buf, 1, l, fd); + } + while (l > 0); + FCLOSE(fs); + FCLOSE(fd); + hbmp = (HBITMAP)LoadImageW(0, tmpname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); + } + if (!hbmp) + { +#ifdef WASABI_COMPILE_SKIN_WA2 + // bitmap not found or broken (like in the netscape skin) + // try to find it in the Classic skin (wa2) + StringW wa2skinFn = WASABI_API_APP->getSkinsPath(); + wa2skinFn.AppendPath("Classic"); + wa2skinFn.AppendPath(_filename); + fs = WFOPEN(wa2skinFn), WF_READONLY_BINARY); + if (fs != OPEN_FAILED) + { + OSFILETYPE fd = WFOPEN(tmpname, L"wb"); + int l; + do + { + char buf[1024] = {0}; + l = FREAD(buf, 1, sizeof(buf), fs); + if (l > 0) FWRITE(buf, 1, l, fd); + } + while (l > 0); + FCLOSE(fs); + FCLOSE(fd); + hbmp = (HBITMAP)LoadImageW(0, tmpname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); + } +#endif //WASABI_COMPILE_SKIN_WA2 + } + if (!hbmp) + { + // no luck :( + _wunlink(tmpname); + return 0; + } + } + + BITMAP bm; + HDC hMemDC, hMemDC2; + HBITMAP hprev, hprev2; + HBITMAP hsrcdib; + void *srcdib; + BITMAPINFO srcbmi = {0, }; + int r = GetObject(hbmp, sizeof(BITMAP), &bm); + ASSERT(r != 0); + *w = bm.bmWidth; + *h = ABS(bm.bmHeight); + + ARGB32 *newbits; + srcbmi.bmiHeader.biSize = sizeof(srcbmi.bmiHeader); + srcbmi.bmiHeader.biWidth = *w; + srcbmi.bmiHeader.biHeight = -*h; + srcbmi.bmiHeader.biPlanes = 1; + srcbmi.bmiHeader.biBitCount = 32; + srcbmi.bmiHeader.biCompression = BI_RGB; + + hMemDC = CreateCompatibleDC(NULL); + hMemDC2 = CreateCompatibleDC(NULL); + hsrcdib = CreateDIBSection(hMemDC, &srcbmi, DIB_RGB_COLORS, &srcdib, NULL, 0); + ASSERTPR(hsrcdib != 0, "CreateDIBSection() failed #69"); + hprev2 = (HBITMAP) SelectObject(hMemDC2, hbmp); + hprev = (HBITMAP) SelectObject(hMemDC, hsrcdib); + BitBlt(hMemDC, 0, 0, *w, *h, hMemDC2, 0, 0, SRCCOPY); + newbits = (ARGB32*)MALLOC((*w) * (*h) * sizeof(ARGB32)); + MEMCPY32(newbits, srcdib, (*w)*(*h) /**sizeof(ARGB32)*/); + { + // put the alpha channel to 255 + unsigned char *b = (unsigned char *)newbits; + int l = (*w) * (*h); + for (int i = 0;i < l;i++) + b[(i*4) + 3] = 0xff; + } + SelectObject(hMemDC, hprev); + SelectObject(hMemDC2, hprev2); + DeleteObject(hsrcdib); + DeleteDC(hMemDC2); + DeleteDC(hMemDC); + + DeleteObject(hbmp); + + if (tmpname[0]) + _wunlink(tmpname); // destroy temp extraction + + if (addMem) + addMemUsage(file, (*w)*(*h)*4); + return newbits; + } + } +#endif + } + return ret; +} + +int imageLoader::getFileType(unsigned char *pData) +{ + // Bmp ? +#ifdef WIN32 + WINBITMAPFILEHEADER * pBFH; + pBFH = (WINBITMAPFILEHEADER *) pData; +#ifdef _WINDOWS + if (pBFH->bfType == 0x4d42) +#else + if (pBFH->bfType == 0x424d) +#endif + return FT_BMP; +#endif + return FT_UNKNOWN; +} + +#ifdef WASABI_COMPILE_SKIN + +ARGB32 *imageLoader::requestSkinBitmap(const wchar_t *id, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) +{ + ifc_xmlreaderparams *params = NULL; + const wchar_t *rootpath = NULL; + + const wchar_t *aliastarget = WASABI_API_PALETTE->getElementAlias(id); + + if (aliastarget) + id = aliastarget; + + const wchar_t *efile = WASABI_API_PALETTE->getSkinBitmapFilename(id, x, y, subw, subh, &rootpath, ¶ms); + + if (x && *x == -1) *x = 0; + if (y && *y == -1) *y = 0; + + if (!efile) + efile = id; + + if (cached) + { + StringPathCombine f(rootpath, efile); + f.toupper(); + f.FixSlashes(); + + int pos = -1; + /*skinCacheEntry *entry = */skinCacheList.findItem(f.getValue(), &pos); + if (pos != -1) + { + //find first one + while (pos > 0 && !wcscmp(skinCacheList[pos - 1]->fullpathfilename, f)) pos--; + do + { + skinCacheEntry *entry = skinCacheList[pos]; + if (GammaMgr::gammaEqual(entry->original_element_id, id) && layerEqual(entry->original_element_id, id)) + { + entry->usageCount++; + if (w) *w = entry->width; + if (h) *h = entry->height; + if (has_alpha) *has_alpha = entry->has_alpha; + return entry->bitmapbits; + } + pos++; + if (pos >= skinCacheList.getNumItems()) break; + } + while (!wcscmp(skinCacheList[pos]->fullpathfilename, f)); + } + } + + int force_nocache = 0; + int t_has_alpha = 0; + ARGB32 *bits = makeBmp(efile, rootpath, &t_has_alpha, w, h, params, TRUE, &force_nocache); + if (has_alpha != NULL) *has_alpha = t_has_alpha; + + if (!bits) + return NULL; + + if (force_nocache || !cached) return bits; + + skinCacheEntry *cachedbmp = new skinCacheEntry; + + if (params) + { + for (size_t i = 0;i != params->getNbItems();i++) + cachedbmp->params.addItem(params->getItemName(i), params->getItemValue(i)); + } + + cachedbmp->usageCount = 1; + cachedbmp->bitmapbits = bits; + cachedbmp->filename = efile; + cachedbmp->has_alpha = !!t_has_alpha; + cachedbmp->width = *w; + cachedbmp->height = *h; + cachedbmp->original_element_id = id; + + //needed for findItem above + StringPathCombine b(rootpath, efile); + b.toupper(); + b.FixSlashes(); + cachedbmp->fullpathfilename.swap(b); + + applySkinFilters(cachedbmp); + skinCacheList.addItem(cachedbmp); + + return cachedbmp->bitmapbits; +} +/* +int imageLoader::paramsMatch(ifc_xmlreaderparams *a, ifc_xmlreaderparams *b) +{ + if (!a && !b) return 1; + if ((!a && b) || (!b && a)) return 0; + for (int i = 0;i < a->getNbItems();i++) + { + const wchar_t *name = a->getItemName(i); + if (!_wcsicmp(name, L"w") || !_wcsicmp(name, L"h") || !_wcsicmp(name, L"x") || !_wcsicmp(name, L"y")) continue; + if (_wcsicmp(a->getItemValue(i), b->getItemValue(name))) + return 0; + } + return 1; +} +*/ +int imageLoader::layerEqual(const wchar_t *id1, const wchar_t *id2) +{ + int a = WASABI_API_PALETTE->getLayerFromId(id1); + int b = WASABI_API_PALETTE->getLayerFromId(id2); + return (a == b); +} + +void imageLoader::releaseSkinBitmap(ARGB32 *bitmapbits) +{ //FG + int i; + // TODO: add critical sections + + int ni = skinCacheList.getNumItems(); + for (i = 0;i < ni;i++) + { + skinCacheEntry *entry = skinCacheList.enumItem(i); + if (entry->bitmapbits == bitmapbits) + { + entry->usageCount--; + if (entry->usageCount == 0) + { + subMemUsage(entry->width*entry->height*sizeof(int)); + WASABI_API_MEMMGR->sysFree(entry->bitmapbits); + skinCacheList.removeByPos(i); + delete entry; + if (skinCacheList.getNumItems() == 0) skinCacheList.removeAll(); + } + return ; + } + } + // bitmap was not a cached skin bitmap, simply free it + release(bitmapbits); +} + +#endif //WASABI_COMPILE_SKIN + +void imageLoader::release(ARGB32 *bitmapbits) +{ + WASABI_API_MEMMGR->sysFree(bitmapbits); +} + +void imageLoader::optimizeHasAlpha(ARGB32 *bits, int len, int *has_alpha) +{ + if (len <= 0 || has_alpha == NULL) return ; + for (*has_alpha = 0; len; len--, bits++) + { + ARGB32 v = *bits; + unsigned int alpha = v >> 24; + if (alpha != 255) + { + *has_alpha = 1; + break; + } + } +} + +#ifdef WASABI_COMPILE_SKIN + +void imageLoader::applySkinFilters() +{ //FG + int i; + + Skin::unloadResources(); + for (i = 0; i < skinCacheList.getNumItems(); i++) + { + skinCacheEntry *entry = skinCacheList.q(i); + applySkinFilters(entry); + } + + WASABI_API_PALETTE->newSkinPart(); + Skin::reloadResources(); +} + +void imageLoader::applySkinFilters(skinCacheEntry *entry) +{ + ASSERT(entry != NULL); + + int w = entry->width, h = entry->height; + + ApplySkinFilters::apply(entry->original_element_id, NULL, (ARGB32*)entry->bitmapbits, w, h); +} + +ARGB32 imageLoader::filterSkinColor(ARGB32 color, const wchar_t *element_id, const wchar_t *groupname) +{ + SkinFilterEnum sfe; + + svc_skinFilter *obj; + while (1) + { + obj = sfe.getNext(FALSE); + if (!obj) break; + color = obj->filterColor(color, element_id, groupname); + sfe.getLastFactory()->releaseInterface(obj); + } + + return color; +} + +#endif //WASABI_COMPILE_SKIN + +void imageLoader::addMemUsage(const wchar_t *filename, int size) +{ + totalMemUsage += size; +#ifdef DEBUG_OUTPUT + DebugStringW("Bitmaps memory usage : %s - %d\n", filename, totalMemUsage); +#endif +} + +void imageLoader::subMemUsage(int size) +{ + totalMemUsage -= size; +} + +#ifdef WASABI_COMPILE_SKIN + +//PtrList<skinCacheEntry> imageLoader::skinCacheList; +PtrListInsertMultiSorted<skinCacheEntry, skinCacheComp> imageLoader::skinCacheList; +#endif //WASABI_COMPILE_SKIN + +int imageLoader::totalMemUsage = 0;
\ No newline at end of file diff --git a/Src/Wasabi/api/imgldr/imgldr.h b/Src/Wasabi/api/imgldr/imgldr.h new file mode 100644 index 00000000..33a64864 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imgldr.h @@ -0,0 +1,86 @@ +#ifndef __IMGLDR_H +#define __IMGLDR_H + +//CUT +#define FT_UNKNOWN 0 +#define FT_BMP 1 +#define FT_JPEG 5 +#define FT_PNG 6 + +#include <bfc/ptrlist.h> +#include <tataki/bitmap/bitmap.h> +#ifdef WASABI_COMPILE_XMLPARSER +#include <api/xml/xmlreader.h> +#include <api/xml/xmlparamsi.h> +#else +class XmlReaderParamsI; +#endif +#ifdef WASABI_COMPILE_SKIN +#include <api/skin/skin.h> +#include <api/skin/skinfilter.h> +#endif + +#include <bfc/string/StringW.h> + +typedef struct { + ARGB32 *bitmapbits; + StringW filename; + int usageCount; + bool has_alpha; + int width; + int height; + StringW includepath; +// String rootpath; + XmlReaderParamsI params; + StringW original_element_id; + StringW fullpathfilename; +} skinCacheEntry; + +typedef unsigned long ARGB32; + +#ifdef WASABI_COMPILE_SKIN + +class skinCacheComp +{ +public: + static int compareItem(void *p1, void *p2) { + return wcscmp(((skinCacheEntry *)p1)->fullpathfilename, ((skinCacheEntry *)p2)->fullpathfilename); + } + static int compareAttrib(const wchar_t *attrib, void *item) { + return wcscmp(attrib, ((skinCacheEntry *)item)->fullpathfilename); + } +}; + +#endif //WASABI_COMPILE_SKIN + +class imageLoader +{ +public: + static ARGB32 *makeBmp(const wchar_t *filename, const wchar_t *path, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params, bool addmem, int *force_nocache); +#ifdef _WIN32 + static ARGB32 *makeBmp(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *forcegroup=NULL); +#endif + static int getFileType(uint8_t *pData); + static StringW getWallpaper(); + static void release(ARGB32 *bitmapbits); +#ifdef WASABI_COMPILE_SKIN + static ARGB32 *requestSkinBitmap(const wchar_t *id, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached=1); + static void releaseSkinBitmap(ARGB32 *bmpbits); + static void applySkinFilters(); + static void applySkinFilters(skinCacheEntry *entry); + static ARGB32 filterSkinColor(ARGB32 color, const wchar_t *elementid, const wchar_t *groupname); + static int layerEqual(const wchar_t *id1, const wchar_t *id2); +#endif //WASABI_COMPILE_SKIN + static int getMemUsage() { return totalMemUsage; } + static int getNumCached() { return skinCacheList.getNumItems(); } +private: +#ifdef WASABI_COMPILE_SKIN + //static int paramsMatch(ifc_xmlreaderparams *a, ifc_xmlreaderparams *b); + static PtrListInsertMultiSorted<skinCacheEntry,skinCacheComp> skinCacheList; +#endif //WASABI_COMPILE_SKIN + static void optimizeHasAlpha(ARGB32 *bits, int len, int *has_alpha); + static void addMemUsage(const wchar_t *filename, int size); + static void subMemUsage(int size); + static int totalMemUsage; +}; +#endif diff --git a/Src/Wasabi/api/imgldr/imgldrapi.cpp b/Src/Wasabi/api/imgldr/imgldrapi.cpp new file mode 100644 index 00000000..45790615 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imgldrapi.cpp @@ -0,0 +1,81 @@ +#include "precomp.h" +#include <api.h> +#include "imgldrapi.h" +#include <api/imgldr/imgldr.h> + +#include <api/skin/skinelem.h> +imgldr_api *imgLoaderApi = NULL; + +ARGB32 *ImgLdrApi::imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h) +{ + if (filename == NULL) + { + DebugString("illegal param : filename == NULL"); + return NULL; + } + return imageLoader::makeBmp(filename, NULL, has_alpha, w, h, NULL, TRUE, NULL); +} + +#ifdef _WIN32 +ARGB32 *ImgLdrApi::imgldr_makeBmp2(HINSTANCE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup) +{ + return imageLoader::makeBmp(hInst, id, has_alpha,w,h, colorgroup); +} +#endif + +void ImgLdrApi::imgldr_releaseBmp(ARGB32 *bmpbits) +{ + if (bmpbits == NULL) { + DebugString("illegal param : bmpbits == NULL"); + return; + } + imageLoader::release(bmpbits); +} + +#ifdef WASABI_COMPILE_SKIN + +ARGB32 *ImgLdrApi::imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached) +{ + if (file == NULL) + { + DebugString("illegal param : file == NULL"); + return NULL; + } + return imageLoader::requestSkinBitmap(file, has_alpha, x, y, subw, subh, w, h, cached); +} + +void ImgLdrApi::imgldr_releaseSkinBitmap(ARGB32 *bmpbits) +{ + if (bmpbits == NULL) + { + DebugString("illegal param : bmpbits == NULL"); + return; + } + imageLoader::releaseSkinBitmap(bmpbits); +} + +RegionServer *ImgLdrApi::imgldr_requestSkinRegion(const wchar_t *id) +{ + if (id == NULL) + { + DebugString("illegal param : id == NULL"); + return NULL; + } + return WASABI_API_PALETTE->requestSkinRegion(id); +} + +void ImgLdrApi::imgldr_cacheSkinRegion(const wchar_t *id, api_region *r) +{ + if (id == NULL) + { + DebugString("illegal param : id == NULL"); + } + if (r == NULL) + { + DebugString("illegal param : region == NULL"); + } + WASABI_API_PALETTE->cacheSkinRegion(id, r); +} + +#endif + diff --git a/Src/Wasabi/api/imgldr/imgldrapi.h b/Src/Wasabi/api/imgldr/imgldrapi.h new file mode 100644 index 00000000..b94fdfa5 --- /dev/null +++ b/Src/Wasabi/api/imgldr/imgldrapi.h @@ -0,0 +1,23 @@ +#ifndef __IMGLDRAPI_H +#define __IMGLDRAPI_H + +#include <api/imgldr/api_imgldr.h> + +class ImgLdrApi : public imgldr_apiI +{ + public: + ARGB32 *imgldr_makeBmp(const wchar_t *filename, int *has_alpha, int *w, int *h); +#ifdef _WIN32 + ARGB32 *imgldr_makeBmp2(OSMODULEHANDLE hInst, int id, int *has_alpha, int *w, int *h, const wchar_t *colorgroup = NULL); +#endif + void imgldr_releaseBmp(ARGB32 *bmpbits); +#ifdef WASABI_COMPILE_SKIN + ARGB32 *imgldr_requestSkinBitmap(const wchar_t *file, int *has_alpha, int *x, int *y, int *subw, int *subh, int *w, int *h, int cached); + RegionServer *imgldr_requestSkinRegion(const wchar_t *id); + void imgldr_cacheSkinRegion(const wchar_t *id, api_region *r); + void imgldr_releaseSkinBitmap(ARGB32 *bmpbits); +#endif //WASABI_COMPILE_SKIN +}; + + +#endif diff --git a/Src/Wasabi/api/imgldr/skinbmps.h b/Src/Wasabi/api/imgldr/skinbmps.h new file mode 100644 index 00000000..dab8568c --- /dev/null +++ b/Src/Wasabi/api/imgldr/skinbmps.h @@ -0,0 +1,122 @@ +#ifndef _SKINBMPS_H +#define _SKINBMPS_H +/* +typedef enum { + SKIN_BITMAP_UNKNOWN, + + // Base texture + SKIN_BITMAP_BASE_TEXTURE, + + // Framewnd + SKIN_BITMAP_FRAME_VERTICAL_DIVIDER, + SKIN_BITMAP_FRAME_HORIZONTAL_DIVIDER, + + // Listwnd/Treewnd + SKIN_BITMAP_LIST_BACKGROUND, + SKIN_BITMAP_TREE_BACKGROUND, + + // Appctrl + SKIN_BITMAP_APPCTRL_LEFTARROW_NONPRESSED, + SKIN_BITMAP_APPCTRL_LEFTARROW_PRESSED, + SKIN_BITMAP_APPCTRL_RIGHTARROW_NONPRESSED, + SKIN_BITMAP_APPCTRL_RIGHTARROW_PRESSED, + SKIN_BITMAP_APPCTRL_WINDOWSIZER, + SKIN_BITMAP_APPCTRL_PLAYERMODE_NONPRESSED, + SKIN_BITMAP_APPCTRL_PLAYERMODE_PRESSED, + SKIN_BITMAP_APPCTRL_MINIMIZE_NONPRESSED, + SKIN_BITMAP_APPCTRL_MINIMIZE_PRESSED, + SKIN_BITMAP_APPCTRL_MAXIMIZE_NONPRESSED, + SKIN_BITMAP_APPCTRL_MAXIMIZE_PRESSED, + SKIN_BITMAP_APPCTRL_CLOSE_NONPRESSED, + SKIN_BITMAP_APPCTRL_CLOSE_PRESSED, + SKIN_BITMAP_APPCTRL_SYSTEMICON, + SKIN_BITMAP_APPCTRL_PLACEHOLDER_LEFT, + SKIN_BITMAP_APPCTRL_PLACEHOLDER_MIDDLE, + SKIN_BITMAP_APPCTRL_PLACEHOLDER_RIGHT, + SKIN_BITMAP_APPCTRL_TITLEBAR, + + // Controls + SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PREVIOUS_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PLAY_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_PAUSE_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_STOP_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_STOP_PRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_NONPRESSED, + SKIN_BITMAP_PLAYBACKCONTROLS_NEXT_PRESSED, + + // Paintset + SKIN_BITMAP_LABEL_UPPERLEFT, + SKIN_BITMAP_LABEL_TOP, + SKIN_BITMAP_LABEL_UPPERRIGHT, + SKIN_BITMAP_LABEL_LEFT, + SKIN_BITMAP_LABEL_MIDDLE, + SKIN_BITMAP_LABEL_RIGHT, + SKIN_BITMAP_LABEL_LOWERLEF, + SKIN_BITMAP_LABEL_BOTTOM, + SKIN_BITMAP_LABEL_LOWERRIGHT, + SKIN_BITMAP_APPBORDER_UPPERLEFT, + SKIN_BITMAP_APPBORDER_TOP, + SKIN_BITMAP_APPBORDER_UPPERRIGHT, + SKIN_BITMAP_APPBORDER_LEFT, + SKIN_BITMAP_APPBORDER_RIGHT, + SKIN_BITMAP_APPBORDER_LOWERLEFT, + SKIN_BITMAP_APPBORDER_BOTTOM, + SKIN_BITMAP_APPBORDER_LOWERRIGHT, + + // Seeker + SKIN_BITMAP_SEEKBAR_LEFT, + SKIN_BITMAP_SEEKBAR_MIDDLE, + SKIN_BITMAP_SEEKBAR_RIGHT, + SKIN_BITMAP_SEEKBAR_BUTTON_NONPRESSED, + SKIN_BITMAP_BUTTON_PRESSED, + + // Status + SKIN_BITMAP_STATUSBAR_LEFT, + SKIN_BITMAP_STATUSBAR_MIDDLE, + SKIN_BITMAP_STATUSBAR_RIGHT, + + // Volbar + SKIN_BITMAP_VOLBAR_LEFT, + SKIN_BITMAP_VOLBAR_MIDDLE, + SKIN_BITMAP_VOLBAR_RIGHT, + SKIN_BITMAP_VOLBAR_BUTTON_NONPRESSED, + SKIN_BITMAP_VOLBAR_BUTTON_PRESSED, + + // Titlewnd + SKIN_BITMAP_COMPONENT_PROP_TOP, + SKIN_BITMAP_COMPONENT_PROP, + SKIN_BITMAP_COMPONENT_PROP_MIDDLE, + SKIN_BITMAP_COMPONENT_PROP_BOTTOM, + + // Videownd + SKIN_BITMAP_MOVIE_BACKGROUND, + + // Seditwnd + SKIN_BITMAP_AVS_SCRIPT_MARKER, + SKIN_BITMAP_AVS_SCRIPT_PLAY_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_PLAY_PRESSED, + SKIN_BITMAP_AVS_SCRIPT_PAUSE_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_PAUSE_PRESSED, + SKIN_BITMAP_AVS_SCRIPT_STOP_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_STOP_PRESSED, + SKIN_BITMAP_AVS_SCRIPT_TIMEARROW, + SKIN_BITMAP_AVS_SCRIPT_BACKGROUND, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_TOP, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_MIDDLE, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BOTTOM, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_NONPRESSED, + SKIN_BITMAP_AVS_SCRIPT_ZOOMER_BUTTON_PRESSED, + +// ComponentAPI1 ends here + NUM_SKIN_BITMAP_ELEMENT_IDS +} SkinBitmapElementId; + +typedef struct { + SkinBitmapElementId id; + char *fn; + } SkinBitmapTableElement; +*/ +#endif diff --git a/Src/Wasabi/api/imgldr/winbmp.h b/Src/Wasabi/api/imgldr/winbmp.h new file mode 100644 index 00000000..afcc0784 --- /dev/null +++ b/Src/Wasabi/api/imgldr/winbmp.h @@ -0,0 +1,47 @@ +#ifndef __WINBMP_H +#define __WINBMP_H + +typedef struct tagWINRGBQUAD +{ + BYTE rgbBlue; + BYTE rgbGreen; + BYTE rgbRed; + BYTE rgbReserved; +} WINRGBQUAD; + +typedef struct tagWINBITMAPFILEHEADER +{ + WORD bfType; + LONG bfSize; + WORD bfReserved1; + WORD bfReserved2; + LONG bfOffBits; +} WINBITMAPFILEHEADER; + +typedef struct tagWINBITMAPINFOHEADER +{ + LONG biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + LONG biCompression; + LONG biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + LONG biClrUsed; + LONG biClrImportant; +} WINBITMAPINFOHEADER; + +typedef struct tagWINBITMAPINFO +{ + WINBITMAPINFOHEADER bmiHeader; + WINRGBQUAD bmiColors[1]; +} WINBITMAPINFO; + +#define BI_RGB 0L +#define BI_RLE8 1L +#define BI_RLE4 2L +#define BI_BITFIELDS 3L + +#endif |