mirror of https://github.com/buggins/dlangui.git
image cache:
This commit is contained in:
parent
dccd5d8f88
commit
a41841b2bc
|
|
@ -18,9 +18,13 @@ uint blendARGB(uint dst, uint src, uint alpha) {
|
|||
|
||||
class DrawBuf : RefCountedObject {
|
||||
protected Rect _clipRect;
|
||||
/// returns current width
|
||||
@property int width() { return 0; }
|
||||
/// returns current height
|
||||
@property int height() { return 0; }
|
||||
/// returns clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
|
||||
@property ref Rect clipRect() { return _clipRect; }
|
||||
/// sets new clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
|
||||
@property void clipRect(const ref Rect rect) {
|
||||
_clipRect = rect;
|
||||
_clipRect.intersect(Rect(0, 0, width, height));
|
||||
|
|
@ -40,6 +44,9 @@ class DrawBuf : RefCountedObject {
|
|||
}
|
||||
void beforeDrawing() { }
|
||||
void afterDrawing() { }
|
||||
/// returns buffer bits per pixel
|
||||
@property int bpp() { return 0; }
|
||||
/// returns pointer to ARGB scanline, null if y is out of range or buffer doesn't provide access to its memory
|
||||
uint * scanLine(int y) { return null; }
|
||||
abstract void resize(int width, int height);
|
||||
abstract void fill(uint color);
|
||||
|
|
@ -52,9 +59,13 @@ class DrawBuf : RefCountedObject {
|
|||
~this() { clear(); }
|
||||
}
|
||||
|
||||
alias DrawBufRef = Ref!DrawBuf;
|
||||
|
||||
class ColorDrawBufBase : DrawBuf {
|
||||
int _dx;
|
||||
int _dy;
|
||||
/// returns buffer bits per pixel
|
||||
override @property int bpp() { return 32; }
|
||||
@property override int width() { return _dx; }
|
||||
@property override int height() { return _dy; }
|
||||
override void fillRect(int left, int top, int right, int bottom, uint color) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,77 @@ module dlangui.graphics.images;
|
|||
import dlangui.graphics.drawbuf;
|
||||
import std.stream;
|
||||
import libpng.png;
|
||||
import core.sys.posix.setjmp;
|
||||
|
||||
/// decoded image cache
|
||||
class ImageCache {
|
||||
|
||||
static class ImageCacheItem {
|
||||
string _filename;
|
||||
DrawBufRef _drawbuf;
|
||||
bool _error; // flag to avoid loading of file if it has been failed once
|
||||
bool _used;
|
||||
this(string filename) {
|
||||
_filename = filename;
|
||||
}
|
||||
@property ref DrawBufRef get() {
|
||||
if (!_drawbuf.isNull || _error) {
|
||||
_used = true;
|
||||
return _drawbuf;
|
||||
}
|
||||
_drawbuf = loadImage(_filename);
|
||||
_used = true;
|
||||
if (_drawbuf.isNull)
|
||||
_error = true;
|
||||
return _drawbuf;
|
||||
}
|
||||
/// remove from memory, will cause reload on next access
|
||||
void compact() {
|
||||
if (!_drawbuf.isNull)
|
||||
_drawbuf.clear();
|
||||
}
|
||||
/// mark as not used
|
||||
void checkpoint() {
|
||||
_used = false;
|
||||
}
|
||||
/// cleanup if unused since last checkpoint
|
||||
void cleanup() {
|
||||
if (!_used)
|
||||
compact();
|
||||
}
|
||||
}
|
||||
ImageCacheItem[string] _map;
|
||||
|
||||
/// get and cache image
|
||||
ref DrawBufRef get(string filename) {
|
||||
if (filename in _map) {
|
||||
return _map[filename].get;
|
||||
}
|
||||
ImageCacheItem item = new ImageCacheItem(filename);
|
||||
_map[filename] = item;
|
||||
return item.get;
|
||||
}
|
||||
// clear usage flags for all entries
|
||||
void checkpoint() {
|
||||
foreach (item; _map)
|
||||
item.checkpoint();
|
||||
}
|
||||
// removes entries not used after last call of checkpoint() or cleanup()
|
||||
void cleanup() {
|
||||
foreach (item; _map)
|
||||
item.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/// load and decode image from file to ColorDrawBuf, returns null if loading or decoding is failed
|
||||
ColorDrawBuf loadImage(string filename) {
|
||||
try {
|
||||
std.stream.File f = new std.stream.File(filename);
|
||||
scope(exit) { f.close(); }
|
||||
return loadImage(f);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// load and decode image from stream to ColorDrawBuf, returns null if loading or decoding is failed
|
||||
ColorDrawBuf loadImage(InputStream stream) {
|
||||
|
|
@ -37,6 +107,7 @@ extern (C) void lvpng_read_func(png_structp png, png_bytep buf, png_size_t len)
|
|||
throw new ImageDecodingException("Error while reading PNG image");
|
||||
}
|
||||
|
||||
/// load and decode PNG image
|
||||
ColorDrawBuf loadPngImage(InputStream stream)
|
||||
{
|
||||
png_structp png_ptr = null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue