mirror of https://github.com/buggins/dlangui.git
embed standard resources
This commit is contained in:
parent
0cac220762
commit
3d8f195e4a
|
@ -31,6 +31,8 @@ version (USE_DEIMAGE) {
|
||||||
version (USE_DLIBIMAGE) {
|
version (USE_DLIBIMAGE) {
|
||||||
import dlib.image.io.io;
|
import dlib.image.io.io;
|
||||||
import dlib.image.image;
|
import dlib.image.image;
|
||||||
|
import dlib.image.io.png;
|
||||||
|
import dlib.image.io.jpeg;
|
||||||
version = ENABLE_DLIBIMAGE_JPEG;
|
version = ENABLE_DLIBIMAGE_JPEG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +41,24 @@ import dlangui.core.types;
|
||||||
import dlangui.graphics.colors;
|
import dlangui.graphics.colors;
|
||||||
import dlangui.graphics.drawbuf;
|
import dlangui.graphics.drawbuf;
|
||||||
import std.stream;
|
import std.stream;
|
||||||
|
import std.path;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
|
|
||||||
|
|
||||||
/// load and decode image from file to ColorDrawBuf, returns null if loading or decoding is failed
|
/// load and decode image from file to ColorDrawBuf, returns null if loading or decoding is failed
|
||||||
ColorDrawBuf loadImage(string filename) {
|
ColorDrawBuf loadImage(string filename) {
|
||||||
|
try {
|
||||||
|
immutable ubyte[] data = cast(immutable ubyte[])std.file.read(filename);
|
||||||
|
return loadImage(data, filename);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("exception while loading image from file ", filename);
|
||||||
|
Log.e(to!string(e));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// load and decode image from input stream to ColorDrawBuf, returns null if loading or decoding is failed
|
||||||
|
ColorDrawBuf loadImage(immutable ubyte[] data, string filename) {
|
||||||
Log.d("Loading image from file " ~ filename);
|
Log.d("Loading image from file " ~ filename);
|
||||||
version (USE_DEIMAGE) {
|
version (USE_DEIMAGE) {
|
||||||
try {
|
try {
|
||||||
|
@ -69,6 +85,7 @@ ColorDrawBuf loadImage(string filename) {
|
||||||
}
|
}
|
||||||
} else version (USE_DLIBIMAGE) {
|
} else version (USE_DLIBIMAGE) {
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
static import dlib.core.stream;
|
||||||
try {
|
try {
|
||||||
version (ENABLE_DLIBIMAGE_JPEG) {
|
version (ENABLE_DLIBIMAGE_JPEG) {
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,19 +93,23 @@ ColorDrawBuf loadImage(string filename) {
|
||||||
if (filename.endsWith(".jpeg") || filename.endsWith(".jpg") || filename.endsWith(".JPG") || filename.endsWith(".JPEG"))
|
if (filename.endsWith(".jpeg") || filename.endsWith(".jpg") || filename.endsWith(".JPG") || filename.endsWith(".JPEG"))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
SuperImage image = dlib.image.io.io.loadImage(filename);
|
SuperImage image = null;
|
||||||
|
dlib.core.stream.ArrayStream dlibstream = new dlib.core.stream.ArrayStream(cast(ubyte[])data, data.length);
|
||||||
|
switch(filename.extension)
|
||||||
|
{
|
||||||
|
case ".jpg", ".JPG", ".jpeg":
|
||||||
|
image = dlib.image.io.jpeg.loadJPEG(dlibstream);
|
||||||
|
break;
|
||||||
|
case ".png", ".PNG":
|
||||||
|
image = dlib.image.io.png.loadPNG(dlibstream);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//SuperImage image = dlib.image.io.io.loadImage(filename);
|
||||||
if (!image)
|
if (!image)
|
||||||
return null;
|
return null;
|
||||||
int w = image.width;
|
ColorDrawBuf buf = importImage(image);
|
||||||
int h = image.height;
|
|
||||||
ColorDrawBuf buf = new ColorDrawBuf(w, h);
|
|
||||||
for (int y = 0; y < h; y++) {
|
|
||||||
uint * dstLine = buf.scanLine(y);
|
|
||||||
for (int x = 0; x < w; x++) {
|
|
||||||
auto pixel = image[x, h - 1 - y].convert(8);
|
|
||||||
dstLine[x] = makeRGBA(pixel.r, pixel.g, pixel.b, 255 - pixel.a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
destroy(image);
|
destroy(image);
|
||||||
return buf;
|
return buf;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -110,6 +131,22 @@ ColorDrawBuf loadImage(string filename) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version (USE_DLIBIMAGE) {
|
||||||
|
ColorDrawBuf importImage(SuperImage image) {
|
||||||
|
int w = image.width;
|
||||||
|
int h = image.height;
|
||||||
|
ColorDrawBuf buf = new ColorDrawBuf(w, h);
|
||||||
|
for (int y = 0; y < h; y++) {
|
||||||
|
uint * dstLine = buf.scanLine(y);
|
||||||
|
for (int x = 0; x < w; x++) {
|
||||||
|
auto pixel = image[x, h - 1 - y].convert(8);
|
||||||
|
dstLine[x] = makeRGBA(pixel.r, pixel.g, pixel.b, 255 - pixel.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ImageDecodingException : Exception {
|
class ImageDecodingException : Exception {
|
||||||
this(string msg) {
|
this(string msg) {
|
||||||
super(msg);
|
super(msg);
|
||||||
|
|
|
@ -37,9 +37,16 @@ import std.conv;
|
||||||
import std.string;
|
import std.string;
|
||||||
import std.path;
|
import std.path;
|
||||||
|
|
||||||
|
/// filename prefix for embedded resources
|
||||||
|
immutable string EMBEDDED_RESOURCE_PREFIX = "@embedded@/";
|
||||||
|
|
||||||
struct EmbeddedResource {
|
struct EmbeddedResource {
|
||||||
string name;
|
immutable string name;
|
||||||
ubyte[] data;
|
immutable ubyte[] data;
|
||||||
|
this(immutable string name, immutable ubyte[] data) {
|
||||||
|
this.name = name;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmbeddedResourceList {
|
struct EmbeddedResourceList {
|
||||||
|
@ -47,23 +54,52 @@ struct EmbeddedResourceList {
|
||||||
void addResources(EmbeddedResource[] resources) {
|
void addResources(EmbeddedResource[] resources) {
|
||||||
list ~= resources;
|
list ~= resources;
|
||||||
}
|
}
|
||||||
|
/// find by exact file name
|
||||||
|
EmbeddedResource * find(string name) {
|
||||||
|
for(int i = 0; i < list.length; i++)
|
||||||
|
if (name.equal(list[i].name))
|
||||||
|
return &list[i];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/// find by name w/o extension
|
||||||
|
EmbeddedResource * findAutoExtension(string name) {
|
||||||
|
string xmlname = name ~ ".xml";
|
||||||
|
string pngname = name ~ ".png";
|
||||||
|
string png9name = name ~ ".9.png";
|
||||||
|
string jpgname = name ~ ".jpg";
|
||||||
|
string jpegname = name ~ ".jpeg";
|
||||||
|
for(int i = 0; i < list.length; i++) {
|
||||||
|
string s = list[i].name;
|
||||||
|
if (s.equal(xmlname) || s.equal(pngname) || s.equal(png9name)
|
||||||
|
|| s.equal(jpgname) || s.equal(jpegname))
|
||||||
|
return &list[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__gshared EmbeddedResourceList embeddedResourceList;
|
__gshared EmbeddedResourceList embeddedResourceList;
|
||||||
|
|
||||||
EmbeddedResource[] embedResource(string resourceName)() {
|
EmbeddedResource[] embedResource(string resourceName)() {
|
||||||
static if ((baseName(resourceName)).length > 0)
|
immutable string name = baseName(resourceName);
|
||||||
return [EmbeddedResource(resourceName, cast(ubyte[])import(baseName(resourceName)))];
|
static if (name.length > 0) {
|
||||||
|
immutable ubyte[] data = cast(immutable ubyte[])import(name);
|
||||||
|
static if (data.length > 0)
|
||||||
|
return [EmbeddedResource(name, data)];
|
||||||
else
|
else
|
||||||
return [];
|
return [];
|
||||||
|
} else
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// embed all resources from list
|
/// embed all resources from list
|
||||||
EmbeddedResource[] embedResources(string[] resourceNames)() {
|
EmbeddedResource[] embedResources(string[] resourceNames)() {
|
||||||
static if (resourceNames.length == 0)
|
static if (resourceNames.length == 0)
|
||||||
return [];
|
return [];
|
||||||
|
static if (resourceNames.length == 1)
|
||||||
|
return embedResource!(resourceNames[0])();
|
||||||
else
|
else
|
||||||
return embedResource!(resourceNames[0])() ~ embedResources!(resourceNames[1..$])();
|
return embedResources!(resourceNames[0 .. $/2])() ~ embedResources!(resourceNames[$/2 .. $])();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// embed all resources from list
|
/// embed all resources from list
|
||||||
|
@ -78,6 +114,24 @@ __gshared static this() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// load resource bytes from embedded resource or file
|
||||||
|
immutable(ubyte[]) loadResourceBytes(string filename) {
|
||||||
|
if (filename.startsWith(EMBEDDED_RESOURCE_PREFIX)) {
|
||||||
|
EmbeddedResource * embedded = embeddedResourceList.find(filename[EMBEDDED_RESOURCE_PREFIX.length .. $]);
|
||||||
|
if (embedded)
|
||||||
|
return embedded.data;
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
immutable ubyte[] data = cast(immutable ubyte[])std.file.read(filename);
|
||||||
|
return data;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("exception while loading file ", filename);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Drawable : RefCountedObject {
|
class Drawable : RefCountedObject {
|
||||||
//private static int _instanceCount;
|
//private static int _instanceCount;
|
||||||
this() {
|
this() {
|
||||||
|
@ -538,7 +592,11 @@ class StateDrawable : Drawable {
|
||||||
import std.string;
|
import std.string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
string s = cast(string)std.file.read(filename);
|
string s = cast(string)loadResourceBytes(filename);
|
||||||
|
if (!s) {
|
||||||
|
Log.e("Cannot read drawable resource from file ", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for well-formedness
|
// Check for well-formedness
|
||||||
//check(s);
|
//check(s);
|
||||||
|
@ -550,9 +608,6 @@ class StateDrawable : Drawable {
|
||||||
} catch (CheckException e) {
|
} catch (CheckException e) {
|
||||||
Log.e("Invalid XML file ", filename);
|
Log.e("Invalid XML file ", filename);
|
||||||
return false;
|
return false;
|
||||||
} catch (Throwable e) {
|
|
||||||
Log.e("Cannot read drawable resource from file ", filename);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,10 +657,13 @@ class ImageCache {
|
||||||
_used = true;
|
_used = true;
|
||||||
return _drawbuf;
|
return _drawbuf;
|
||||||
}
|
}
|
||||||
_drawbuf = loadImage(_filename);
|
immutable ubyte[] data = loadResourceBytes(_filename);
|
||||||
|
if (data) {
|
||||||
|
_drawbuf = loadImage(data, _filename);
|
||||||
if (_filename.endsWith(".9.png"))
|
if (_filename.endsWith(".9.png"))
|
||||||
_drawbuf.detectNinePatch();
|
_drawbuf.detectNinePatch();
|
||||||
_used = true;
|
_used = true;
|
||||||
|
}
|
||||||
if (_drawbuf.isNull)
|
if (_drawbuf.isNull)
|
||||||
_error = true;
|
_error = true;
|
||||||
return _drawbuf;
|
return _drawbuf;
|
||||||
|
@ -917,6 +975,12 @@ class DrawableCache {
|
||||||
return id; // it's not a file name, just a color #AARRGGBB
|
return id; // it's not a file name, just a color #AARRGGBB
|
||||||
if (id in _idToFileMap)
|
if (id in _idToFileMap)
|
||||||
return _idToFileMap[id];
|
return _idToFileMap[id];
|
||||||
|
EmbeddedResource * embedded = embeddedResourceList.findAutoExtension(id);
|
||||||
|
if (embedded) {
|
||||||
|
string fn = EMBEDDED_RESOURCE_PREFIX ~ embedded.name;
|
||||||
|
_idToFileMap[id] = fn;
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
foreach(string path; _resourcePaths) {
|
foreach(string path; _resourcePaths) {
|
||||||
string fn;
|
string fn;
|
||||||
fn = checkFileName(path, id, ".xml");
|
fn = checkFileName(path, id, ".xml");
|
||||||
|
|
|
@ -1278,7 +1278,11 @@ bool loadTheme(Theme theme, string resourceId, int level = 0) {
|
||||||
filename = drawableCache.findResource(resourceId);
|
filename = drawableCache.findResource(resourceId);
|
||||||
if (!filename || !filename.endsWith(".xml"))
|
if (!filename || !filename.endsWith(".xml"))
|
||||||
return false;
|
return false;
|
||||||
string s = cast(string)std.file.read(filename);
|
string s = cast(string)loadResourceBytes(filename);
|
||||||
|
if (!s) {
|
||||||
|
Log.e("Cannot read XML resource ", resourceId, " from file ", filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for well-formedness
|
// Check for well-formedness
|
||||||
//check(s);
|
//check(s);
|
||||||
|
@ -1290,9 +1294,6 @@ bool loadTheme(Theme theme, string resourceId, int level = 0) {
|
||||||
} catch (CheckException e) {
|
} catch (CheckException e) {
|
||||||
Log.e("Invalid XML resource ", resourceId);
|
Log.e("Invalid XML resource ", resourceId);
|
||||||
return false;
|
return false;
|
||||||
} catch (Throwable e) {
|
|
||||||
Log.e("Cannot read XML resource ", resourceId, " from file ", filename, " exception: ", e);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue