osedge.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "precomp.h"
  2. #include "osedge.h"
  3. #include <api/xml/xmlparams.h>
  4. #include <bfc/parse/pathparse.h>
  5. #include <api/memmgr/api_memmgr.h>
  6. #ifndef _WASABIRUNTIME
  7. BEGIN_SERVICES(OsEdgeGen_Svc);
  8. DECLARE_SERVICETSINGLE(svc_imageGenerator, OsEdgeImage);
  9. END_SERVICES(OsEdgeGen_Svc, _OsEdgeGen_Svc);
  10. #ifdef _X86_
  11. extern "C" { int _link_OsEdgeGen_Svc; }
  12. #else
  13. extern "C" { int __link_OsEdgeGen_Svc; }
  14. #endif
  15. #endif
  16. int OsEdgeImage::testDesc(const wchar_t *desc) {
  17. return !_wcsicmp(desc, L"$osedge");
  18. }
  19. ARGB32 *OsEdgeImage::genImage(const wchar_t *desc, int *has_alpha, int *w, int *h, ifc_xmlreaderparams *params)
  20. {
  21. int _w = params->getItemValueInt(L"w", 1);
  22. if (_w == 0) _w = 1;
  23. int _h = params->getItemValueInt(L"h", 1);
  24. if (_h == 0) _h = 1;
  25. if (_w <= 0 || _h <= 0) return NULL;
  26. #ifdef WASABI_COMPILE_MEMMGR
  27. ARGB32 *ret = (ARGB32*)WASABI_API_MEMMGR->sysMalloc(_w * _h * sizeof(ARGB32));
  28. #else
  29. ARGB32 *ret = (ARGB32*)MALLOC(_w * _h * sizeof(ARGB32));
  30. #endif
  31. RECT r = Wasabi::Std::makeRect(0, 0, _w, _h);
  32. BITMAPINFO bmi;
  33. ZERO(bmi);
  34. bmi.bmiHeader.biSize = sizeof(bmi);
  35. bmi.bmiHeader.biWidth = _w;
  36. bmi.bmiHeader.biHeight = -_h;
  37. bmi.bmiHeader.biPlanes = 1;
  38. bmi.bmiHeader.biBitCount = 32;
  39. bmi.bmiHeader.biCompression = BI_RGB;
  40. // the rest are 0
  41. ARGB32 *bits;
  42. HBITMAP hbmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
  43. HDC hdc = CreateCompatibleDC(NULL);
  44. HBITMAP prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
  45. unsigned long edgev = 0;
  46. if (!_wcsicmp(params->getItemValue(L"edge"), L"bump")) edgev = EDGE_BUMP;
  47. else if (!_wcsicmp(params->getItemValue(L"edge"), L"etched")) edgev = EDGE_ETCHED;
  48. else if (!_wcsicmp(params->getItemValue(L"edge"), L"raised")) edgev = EDGE_RAISED;
  49. else if (!_wcsicmp(params->getItemValue(L"edge"), L"sunken")) edgev = EDGE_SUNKEN;
  50. if (edgev == 0) edgev = EDGE_RAISED;
  51. unsigned long sides = 0;
  52. PathParserW pp(params->getItemValue(L"sides"), L",");
  53. for (int i = 0; i < pp.getNumStrings(); i++) {
  54. const wchar_t *p = pp.enumString(i);
  55. if (!_wcsicmp(p, L"left")) sides |= BF_LEFT;
  56. if (!_wcsicmp(p, L"top")) sides |= BF_TOP;
  57. if (!_wcsicmp(p, L"right")) sides |= BF_RIGHT;
  58. if (!_wcsicmp(p, L"bottom")) sides |= BF_BOTTOM;
  59. if (!_wcsicmp(p, L"all")) sides |= BF_RECT;
  60. if (!_wcsicmp(p, L"middle")) sides |= BF_MIDDLE;
  61. if (!_wcsicmp(p, L"flat")) sides |= BF_FLAT;
  62. if (!_wcsicmp(p, L"soft")) sides |= BF_SOFT;
  63. if (!_wcsicmp(p, L"mono")) sides |= BF_MONO;
  64. }
  65. // DO EET
  66. DrawEdge(hdc, &r, edgev, sides);
  67. MEMCPY(ret, bits, sizeof(ARGB32) * _w * _h);
  68. for (int i = 0; i < _w * _h; i++) { // force alpha
  69. ret[i] |= 0xff000000;
  70. }
  71. SelectObject(hdc, prevbmp);
  72. DeleteDC(hdc);
  73. DeleteObject(hbmp);
  74. *w = _w;
  75. *h = _h;
  76. *has_alpha = 1; // will be optimized anyway
  77. return ret;
  78. }