diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d index e4de8b01..abea1d5a 100644 --- a/src/dlangui/core/types.d +++ b/src/dlangui/core/types.d @@ -643,3 +643,76 @@ dstring normalizeEndOfLineCharacters(dstring s) { } return cast(dstring)res; } + +/// C malloc allocated array wrapper +struct MallocBuf(T) { + import core.stdc.stdlib : realloc, free; + private T * _allocated; + private uint _allocatedSize; + private uint _length; + /// get pointer + @property T * ptr() { return _allocated; } + /// get length + @property uint length() { return _length; } + /// set new length + @property void length(uint len) { + if (len > _allocatedSize) { + reserve(_allocatedSize ? len * 2 : len); + } + _length = len; + } + /// const array[index]; + T opIndex(uint index) const { + assert(index < _length); + return _allocated[index]; + } + /// ref array[index]; + ref T opIndex(uint index) { + assert(index < _length); + return _allocated[index]; + } + /// array[index] = value; + void opIndexAssign(uint index, T value) { + assert(index < _length); + _allocated[index] = value; + } + /// array[index] = value; + void opIndexAssign(uint index, T[] values) { + assert(index + values.length < _length); + _allocated[index .. index + values.length] = values[]; + } + /// array[a..b] + T[] opSlice(uint a, uint b) { + assert(a <= b && b <= _length); + return _allocated[a .. b]; + } + /// array[] + T[] opSlice() { + return _allocated ? _allocated[0 .. _length] : null; + } + /// array[$] + uint opDollar() { return _length; } + ~this() { + clear(); + } + /// free allocated memory, set length to 0 + void clear() { + if (_allocated) + free(_allocated); + _allocatedSize = 0; + _length = 0; + } + /// make sure buffer capacity is at least (size) items + void reserve(uint size) { + if (_allocatedSize < size) { + _allocated = cast(T*)realloc(_allocated, T.sizeof * size); + _allocatedSize = size; + } + } + /// fill buffer with specified value + void fill(T value) { + if (_length) { + _allocated[0 .. _length] = value; + } + } +} diff --git a/src/dlangui/graphics/drawbuf.d b/src/dlangui/graphics/drawbuf.d index 33024b96..92811910 100644 --- a/src/dlangui/graphics/drawbuf.d +++ b/src/dlangui/graphics/drawbuf.d @@ -1233,14 +1233,15 @@ class ColorDrawBufBase : DrawBuf { } class GrayDrawBuf : DrawBuf { - int _dx; - int _dy; + protected int _dx; + protected int _dy; /// returns buffer bits per pixel override @property int bpp() { return 8; } @property override int width() { return _dx; } @property override int height() { return _dy; } - ubyte[] _buf; + protected MallocBuf!ubyte _buf; + this(int width, int height) { resize(width, height); } @@ -1473,7 +1474,7 @@ class GrayDrawBuf : DrawBuf { } class ColorDrawBuf : ColorDrawBufBase { - uint[] _buf; + protected MallocBuf!uint _buf; /// create ARGB8888 draw buf of specified width and height this(int width, int height) { @@ -1482,9 +1483,8 @@ class ColorDrawBuf : ColorDrawBufBase { /// create copy of ColorDrawBuf this(ColorDrawBuf v) { this(v.width, v.height); - //_buf.length = v._buf.length; - foreach(i; 0 .. _buf.length) - _buf[i] = v._buf[i]; + if (auto len = _buf.length) + _buf.ptr[0 .. len] = v._buf.ptr[0 .. len]; } /// create resized copy of ColorDrawBuf this(ColorDrawBuf v, int dx, int dy) { @@ -1494,7 +1494,7 @@ class ColorDrawBuf : ColorDrawBufBase { } void invertAndPreMultiplyAlpha() { - foreach(ref pixel; _buf) { + foreach(ref pixel; _buf[]) { uint a = (pixel >> 24) & 0xFF; uint r = (pixel >> 16) & 0xFF; uint g = (pixel >> 8) & 0xFF; @@ -1510,12 +1510,12 @@ class ColorDrawBuf : ColorDrawBufBase { } void invertAlpha() { - foreach(ref pixel; _buf) + foreach(ref pixel; _buf[]) pixel ^= 0xFF000000; } void invertByteOrder() { - foreach(ref pixel; _buf) { + foreach(ref pixel; _buf[]) { pixel = (pixel & 0xFF00FF00) | ((pixel & 0xFF0000) >> 16) | ((pixel & 0xFF) << 16); @@ -1524,7 +1524,7 @@ class ColorDrawBuf : ColorDrawBufBase { // for passing of image to OpenGL texture void invertAlphaAndByteOrder() { - foreach(ref pixel; _buf) { + foreach(ref pixel; _buf[]) { pixel = ((pixel & 0xFF00FF00) | ((pixel & 0xFF0000) >> 16) | ((pixel & 0xFF) << 16)); @@ -1643,9 +1643,9 @@ class ColorDrawBuf : ColorDrawBufBase { uint[] tmpbuf; tmpbuf.length = _buf.length; // do horizontal blur - blurOneDimension(_buf, tmpbuf, blurSize, true); + blurOneDimension(_buf[], tmpbuf, blurSize, true); // then do vertical blur - blurOneDimension(tmpbuf, _buf, blurSize, false); + blurOneDimension(tmpbuf, _buf[], blurSize, false); } }