e - wallpaper gen - generate multiple resolutions for wallpapers
pre-scale a bunch of resolutions for generated wallpaper files that intersect with common resolution sizes so e will automatically load the nearest resolution to be more efficient on load to only decode what is needed. a bi-product is that e now has a wallapper gen tool that is simpler than writing your own edc files... :) @feature
This commit is contained in:
parent
1c237e4c3e
commit
3f22a0c26d
5
TODO
5
TODO
|
@ -119,9 +119,8 @@ TODO:
|
|||
* set user password
|
||||
* user cron front-end config/editor
|
||||
* allow separate LC_MESSAGES, LC_TIME, LC_NUMERIC, LC_NAME, etc.
|
||||
* wallpaper: gen wp files with multiple common resolutions in image set
|
||||
* edje needs logic to handle max texture size and to downsize to work
|
||||
* rpi max texture size is 2048...
|
||||
* edje needs logic to handle max texture size to fix big img problems
|
||||
* rpi max texture size is 2048...
|
||||
* dnd: remove e_dnd and use elm's dnd instead
|
||||
* new gadgets:
|
||||
* be able to move, resize etc. without alt move/resize mode like old)
|
||||
|
|
|
@ -13,24 +13,16 @@ static Eina_Bool _import_cb_edje_cc_exit(void *data, int type, void *event);
|
|||
static void
|
||||
_import_edj_gen(E_Import_Config_Dialog *import)
|
||||
{
|
||||
Evas *evas;
|
||||
Evas_Object *img;
|
||||
Eina_Bool anim = EINA_FALSE;
|
||||
int fd, num = 1;
|
||||
int w = 0, h = 0;
|
||||
const char *file, *locale;
|
||||
char buf[PATH_MAX], fbuf[PATH_MAX], cmd[PATH_MAX + PATH_MAX + 40], tmpn[PATH_MAX], ipart[PATH_MAX], enc[128];
|
||||
Eina_Tmpstr *path = NULL;
|
||||
char *imgdir = NULL, *fstrip;
|
||||
int cr, cg, cb, ca;
|
||||
FILE *f;
|
||||
const char *file, *fill, *s;
|
||||
char buf[PATH_MAX], fbuf[PATH_MAX], cmd[PATH_MAX + PATH_MAX + 40];
|
||||
char *fstrip, *infile, *outfile;
|
||||
int num, cr, cg, cb;
|
||||
size_t len, off;
|
||||
|
||||
evas = evas_object_evas_get(import->dia->win);
|
||||
file = ecore_file_file_get(import->file);
|
||||
fstrip = ecore_file_strip_ext(file);
|
||||
if (!fstrip) return;
|
||||
len = e_user_dir_snprintf(buf, sizeof(buf), "backgrounds/%s.edj", fstrip);
|
||||
len = e_user_dir_snprintf(buf, sizeof(buf), "backgrounds/.tmp.%s.edj", fstrip);
|
||||
if (len >= sizeof(buf))
|
||||
{
|
||||
free(fstrip);
|
||||
|
@ -43,238 +35,47 @@ _import_edj_gen(E_Import_Config_Dialog *import)
|
|||
cr = import->color.r;
|
||||
cg = import->color.g;
|
||||
cb = import->color.b;
|
||||
ca = import->color.a;
|
||||
|
||||
if (num == 100)
|
||||
{
|
||||
printf("Couldn't come up with another filename for %s\n", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(tmpn, "e_bgdlg_new.edc-tmp-XXXXXX");
|
||||
fd = eina_file_mkstemp(tmpn, &path);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("Error Creating tmp file: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
f = fdopen(fd, "w");
|
||||
if (!f)
|
||||
{
|
||||
printf("Cannot open %s for writing\n", tmpn);
|
||||
return;
|
||||
}
|
||||
|
||||
anim = eina_str_has_extension(import->file, "gif");
|
||||
imgdir = ecore_file_dir_get(import->file);
|
||||
if (!imgdir) ipart[0] = '\0';
|
||||
else
|
||||
{
|
||||
snprintf(ipart, sizeof(ipart), "-id %s", e_util_filename_escape(imgdir));
|
||||
free(imgdir);
|
||||
}
|
||||
|
||||
img = evas_object_image_add(evas);
|
||||
evas_object_image_file_set(img, import->file, NULL);
|
||||
evas_object_image_size_get(img, &w, &h);
|
||||
evas_object_del(img);
|
||||
|
||||
if (import->external)
|
||||
{
|
||||
const char *esc = e_util_filename_escape(import->file);
|
||||
fstrip = memcpy(fbuf, esc, strlen(esc) + 1);
|
||||
snprintf(enc, sizeof(enc), "USER");
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *esc = e_util_filename_escape(file);
|
||||
fstrip = memcpy(fbuf, esc, strlen(esc) + 1);
|
||||
if (import->quality == 100)
|
||||
snprintf(enc, sizeof(enc), "COMP");
|
||||
else
|
||||
snprintf(enc, sizeof(enc), "LOSSY %i", import->quality);
|
||||
}
|
||||
switch (import->method)
|
||||
{
|
||||
case IMPORT_STRETCH:
|
||||
fprintf(f,
|
||||
"images { image: \"%s\" %s; }\n"
|
||||
"collections {\n"
|
||||
"group { name: \"e/desktop/background\";\n"
|
||||
"%s"
|
||||
"data { item: \"style\" \"0\"; }\n"
|
||||
"parts {\n"
|
||||
"part { name: \"bg\"; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"image { normal: \"%s\"; scale_hint: STATIC; }\n"
|
||||
"} } } } }\n"
|
||||
, fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", fstrip);
|
||||
break;
|
||||
|
||||
case IMPORT_TILE:
|
||||
fprintf(f,
|
||||
"images { image: \"%s\" %s; }\n"
|
||||
"collections {\n"
|
||||
"group { name: \"e/desktop/background\";\n"
|
||||
"data { item: \"style\" \"1\"; }\n"
|
||||
"%s"
|
||||
"parts {\n"
|
||||
"part { name: \"bg\"; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"image { normal: \"%s\"; }\n"
|
||||
"fill { size {\n"
|
||||
"relative: 0.0 0.0;\n"
|
||||
"offset: %i %i;\n"
|
||||
"} } } } } } }\n"
|
||||
, fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", fstrip, w, h);
|
||||
break;
|
||||
|
||||
case IMPORT_CENTER:
|
||||
fprintf(f,
|
||||
"images { image: \"%s\" %s; }\n"
|
||||
"collections {\n"
|
||||
"group { name: \"e/desktop/background\";\n"
|
||||
"data { item: \"style\" \"2\"; }\n"
|
||||
"%s"
|
||||
"parts {\n"
|
||||
"part { name: \"col\"; type: RECT; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"color: %i %i %i %i;\n"
|
||||
"} }\n"
|
||||
"part { name: \"bg\"; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"min: %i %i; max: %i %i;\n"
|
||||
"image { normal: \"%s\"; }\n"
|
||||
"} } } } }\n"
|
||||
, fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n", cr, cg, cb, ca, w, h, w, h, fstrip);
|
||||
break;
|
||||
|
||||
case IMPORT_SCALE_ASPECT_IN:
|
||||
locale = e_intl_language_get();
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
fprintf(f,
|
||||
"images { image: \"%s\" %s; }\n"
|
||||
"collections {\n"
|
||||
"group { name: \"e/desktop/background\";\n"
|
||||
"data { item: \"style\" \"3\"; }\n"
|
||||
"%s"
|
||||
"parts {\n"
|
||||
"part { name: \"col\"; type: RECT; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"color: %i %i %i %i;\n"
|
||||
"} }\n"
|
||||
"part { name: \"bg\"; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"aspect: %1.9f %1.9f; aspect_preference: BOTH;\n"
|
||||
"image { normal: \"%s\"; scale_hint: STATIC; }\n"
|
||||
"} } } } }\n"
|
||||
, fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n",
|
||||
cr, cg, cb, ca, (double)w / (double)h, (double)w / (double)h, fstrip);
|
||||
setlocale(LC_NUMERIC, locale);
|
||||
break;
|
||||
|
||||
case IMPORT_SCALE_ASPECT_OUT:
|
||||
locale = e_intl_language_get();
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
fprintf(f,
|
||||
"images { image: \"%s\" %s; }\n"
|
||||
"collections {\n"
|
||||
"group { name: \"e/desktop/background\";\n"
|
||||
"data { item: \"style\" \"4\"; }\n"
|
||||
"%s"
|
||||
"parts {\n"
|
||||
"part { name: \"bg\"; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"aspect: %1.9f %1.9f; aspect_preference: NONE;\n"
|
||||
"image { normal: \"%s\"; scale_hint: STATIC; }\n"
|
||||
"} } } } }\n"
|
||||
, fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n",
|
||||
(double)w / (double)h, (double)w / (double)h, fstrip);
|
||||
setlocale(LC_NUMERIC, locale);
|
||||
break;
|
||||
|
||||
case IMPORT_PAN:
|
||||
locale = e_intl_language_get();
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
fprintf(f,
|
||||
"images { image: \"%s\" %s; }\n"
|
||||
"collections {\n"
|
||||
"group { name: \"e/desktop/background\";\n"
|
||||
"data { item: \"style\" \"4\"; }\n"
|
||||
"%s"
|
||||
"script {\n"
|
||||
"public cur_anim; public cur_x; public cur_y; public prev_x;\n"
|
||||
"public prev_y; public total_x; public total_y; \n"
|
||||
"public pan_bg(val, Float:v) {\n"
|
||||
"new Float:x, Float:y, Float:px, Float: py;\n"
|
||||
|
||||
"px = get_float(prev_x); py = get_float(prev_y);\n"
|
||||
"if (get_int(total_x) > 1) {\n"
|
||||
"x = float(get_int(cur_x)) / (get_int(total_x) - 1);\n"
|
||||
"x = px - (px - x) * v;\n"
|
||||
"} else { x = 0.0; v = 1.0; }\n"
|
||||
"if (get_int(total_y) > 1) {\n"
|
||||
"y = float(get_int(cur_y)) / (get_int(total_y) - 1);\n"
|
||||
"y = py - (py - y) * v;\n"
|
||||
"} else { y = 0.0; v = 1.0; }\n"
|
||||
|
||||
"set_state_val(PART:\"bg\", STATE_ALIGNMENT, x, y);\n"
|
||||
|
||||
"if (v >= 1.0) {\n"
|
||||
"set_int(cur_anim, 0); set_float(prev_x, x);\n"
|
||||
"set_float(prev_y, y); return 0;\n"
|
||||
"}\n"
|
||||
"return 1;\n"
|
||||
"}\n"
|
||||
"public message(Msg_Type:type, id, ...) {\n"
|
||||
"if ((type == MSG_FLOAT_SET) && (id == 0)) {\n"
|
||||
"new ani;\n"
|
||||
|
||||
"get_state_val(PART:\"bg\", STATE_ALIGNMENT, prev_x, prev_y);\n"
|
||||
"set_int(cur_x, round(getfarg(3))); set_int(total_x, round(getfarg(4)));\n"
|
||||
"set_int(cur_y, round(getfarg(5))); set_int(total_y, round(getfarg(6)));\n"
|
||||
|
||||
"ani = get_int(cur_anim); if (ani > 0) cancel_anim(ani);\n"
|
||||
"ani = anim(getfarg(2), \"pan_bg\", 0); set_int(cur_anim, ani);\n"
|
||||
"} } }\n"
|
||||
"parts {\n"
|
||||
"part { name: \"bg\"; mouse_events: 0;\n"
|
||||
"description { state: \"default\" 0.0;\n"
|
||||
"aspect: %1.9f %1.9f; aspect_preference: NONE;\n"
|
||||
"image { normal: \"%s\"; scale_hint: STATIC; }\n"
|
||||
"} } }\n"
|
||||
"programs { program {\n"
|
||||
" name: \"init\";\n"
|
||||
" signal: \"load\";\n"
|
||||
" source: \"\";\n"
|
||||
" script { custom_state(PART:\"bg\", \"default\", 0.0);\n"
|
||||
" set_state(PART:\"bg\", \"custom\", 0.0);\n"
|
||||
" set_float(prev_x, 0.0); set_float(prev_y, 0.0);\n"
|
||||
"} } } } }\n"
|
||||
, fstrip, enc, anim ? "" : "data.item: \"noanimation\" \"1\";\n",
|
||||
(double)w / (double)h, (double)w / (double)h, fstrip);
|
||||
setlocale(LC_NUMERIC, locale);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* won't happen */
|
||||
break;
|
||||
case IMPORT_STRETCH: fill = "stretch"; break;
|
||||
case IMPORT_TILE: fill = "tile"; break;
|
||||
case IMPORT_CENTER: fill = "center"; break;
|
||||
case IMPORT_SCALE_ASPECT_IN: fill = "scale_in"; break;
|
||||
case IMPORT_SCALE_ASPECT_OUT: fill = "scale_out"; break;
|
||||
case IMPORT_PAN: fill = "pan"; break;
|
||||
default: return; break;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "%s/edje_cc -v %s %s %s", e_prefix_bin_get(),
|
||||
ipart, path, e_util_filename_escape(buf));
|
||||
|
||||
import->tmpf = strdup(tmpn);
|
||||
s = e_util_filename_escape(import->file);
|
||||
if (s) infile = strdup(s);
|
||||
else return;
|
||||
s = e_util_filename_escape(buf);
|
||||
if (s) outfile = strdup(s);
|
||||
else
|
||||
{
|
||||
free(infile);
|
||||
return;
|
||||
}
|
||||
snprintf(fbuf, sizeof(fbuf), "%s/edje_cc", e_prefix_bin_get());
|
||||
if (!ecore_file_can_exec(fbuf))
|
||||
snprintf(fbuf, sizeof(fbuf), "edje_cc");
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"%s/enlightenment/utils/enlightenment_wallpaper_gen "
|
||||
"%s %s %s %s %i %i %i %i",
|
||||
e_prefix_lib_get(),
|
||||
fbuf, fill, infile, outfile, import->quality, cr, cg, cb);
|
||||
free(infile);
|
||||
free(outfile);
|
||||
import->fdest = eina_stringshare_add(buf);
|
||||
import->exe_handler =
|
||||
ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||
_import_cb_edje_cc_exit, import);
|
||||
import->exe_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
|
||||
_import_cb_edje_cc_exit,
|
||||
import);
|
||||
import->exe = ecore_exe_run(cmd, import);
|
||||
|
||||
eina_tmpstr_del(path);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
|
@ -298,6 +99,29 @@ _import_cb_edje_cc_exit(void *data, EINA_UNUSED int type, void *event)
|
|||
|
||||
if (r && import->ok)
|
||||
{
|
||||
char *p, *newfile = strdup(import->fdest);
|
||||
|
||||
if (!newfile)
|
||||
{
|
||||
e_object_del(E_OBJECT(import));
|
||||
return ECORE_CALLBACK_DONE;
|
||||
}
|
||||
p = strrchr(newfile, '/');
|
||||
if (!p)
|
||||
{
|
||||
e_object_del(E_OBJECT(import));
|
||||
return ECORE_CALLBACK_DONE;
|
||||
}
|
||||
// strip out the .tmp. before the name
|
||||
for (p = p + 1; ; p++)
|
||||
{
|
||||
*p = p[5];
|
||||
if (*p == 0) break;
|
||||
}
|
||||
ecore_file_mv(import->fdest, newfile);
|
||||
eina_stringshare_replace(&(import->fdest), newfile);
|
||||
free(newfile);
|
||||
|
||||
e_object_ref(E_OBJECT(import));
|
||||
import->ok((void *)import->fdest, import);
|
||||
e_object_del(E_OBJECT(import));
|
||||
|
@ -409,9 +233,6 @@ _e_import_config_dialog_del(void *data)
|
|||
|
||||
if (import->exe_handler) ecore_event_handler_del(import->exe_handler);
|
||||
import->exe_handler = NULL;
|
||||
if (import->tmpf && (unlink(import->tmpf) < 0))
|
||||
ERR("Could not delete tmpfile '%s'", import->tmpf);
|
||||
free(import->tmpf);
|
||||
eina_stringshare_del(import->fdest);
|
||||
import->exe = NULL;
|
||||
eina_stringshare_del(import->file);
|
||||
|
@ -462,12 +283,10 @@ e_import_config_dialog_show(Evas_Object *parent, const char *path, Ecore_End_Cb
|
|||
dia->data = import;
|
||||
import->dia = dia;
|
||||
import->ok = ok, import->cancel = cancel;
|
||||
import->path = eina_stringshare_add(path);
|
||||
e_object_del_attach_func_set(E_OBJECT(dia), _e_import_config_dia_del);
|
||||
evas_object_event_callback_add(dia->win, EVAS_CALLBACK_DEL, _e_import_config_dialog_win_del, dia);
|
||||
|
||||
import->method = IMPORT_SCALE_ASPECT_OUT;
|
||||
import->external = 0;
|
||||
import->quality = 90;
|
||||
import->file = eina_stringshare_add(path);
|
||||
|
||||
|
@ -522,11 +341,9 @@ e_import_config_dialog_show(Evas_Object *parent, const char *path, Ecore_End_Cb
|
|||
ol = e_widget_list_add(evas, 0, 1);
|
||||
|
||||
of = e_widget_frametable_add(evas, _("File Quality"), 0);
|
||||
ord = e_widget_check_add(evas, _("Use original file"), &(import->external));
|
||||
e_widget_frametable_object_append(of, ord, 0, 0, 1, 1, 1, 0, 1, 0);
|
||||
ord = e_widget_slider_add(evas, 1, 0, _("%3.0f%%"), 0.0, 100.0, 1.0, 0,
|
||||
NULL, &(import->quality), 150);
|
||||
e_widget_frametable_object_append(of, ord, 0, 1, 1, 1, 1, 0, 1, 0);
|
||||
e_widget_frametable_object_append(of, ord, 0, 0, 1, 1, 1, 0, 1, 0);
|
||||
e_widget_list_object_append(ol, of, 1, 1, 0);
|
||||
|
||||
of = e_widget_framelist_add(evas, _("Fill Color"), 0);
|
||||
|
|
|
@ -7,21 +7,18 @@ typedef struct _E_Import_Config_Dialog E_Import_Config_Dialog;
|
|||
#define E_IMPORT_CONFIG_DIALOG_TYPE 0xE0b01040
|
||||
struct _E_Import_Config_Dialog
|
||||
{
|
||||
E_Object e_obj_inherit;
|
||||
Ecore_End_Cb ok;
|
||||
Ecore_Cb cancel;
|
||||
E_Object e_obj_inherit;
|
||||
Ecore_End_Cb ok;
|
||||
Ecore_Cb cancel;
|
||||
|
||||
const char *file;
|
||||
int method;
|
||||
int external;
|
||||
int quality;
|
||||
const char *file;
|
||||
int method;
|
||||
int quality;
|
||||
E_Color color;
|
||||
|
||||
Ecore_Exe *exe;
|
||||
Ecore_Event_Handler *exe_handler;
|
||||
const char *path;
|
||||
char *tmpf;
|
||||
const char *fdest;
|
||||
const char *fdest;
|
||||
|
||||
E_Dialog *dia;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,499 @@
|
|||
#include <Elementary.h>
|
||||
#include "config.h"
|
||||
|
||||
// a set of commonly found resolution buckets to try size the image down
|
||||
// to to match width OR height so we can avoid decoding a larger image from
|
||||
// disk making startup time faster by picking the right res that's encoded
|
||||
// already in the file... the more resolutions we encode the bigger
|
||||
// the file so it's a tradeoff, thus commenting out a lot of the resolutions
|
||||
// because they are so close or can just miildly crop another res...
|
||||
// only encode resolutiosn less than the original image a well as throw in
|
||||
// the original as the highest res option
|
||||
// pick onne of each y resolution and scale accordingly so e.g. Nx480, Nx600,
|
||||
// Nx720, Nx788, Nx800, Nx900, ...
|
||||
static const int resolutions[] =
|
||||
{
|
||||
// not bothering below 640x480
|
||||
// 640, 480,
|
||||
// 800, 480,
|
||||
854, 480,
|
||||
// 768, 576,
|
||||
// 1024, 576,
|
||||
// 800, 600,
|
||||
1024, 600,
|
||||
1280, 720,
|
||||
// 1024, 768,
|
||||
// 1152, 768
|
||||
// 1280, 768
|
||||
1366, 768,
|
||||
1280, 800,
|
||||
// 1280, 854,
|
||||
// 1152, 864,
|
||||
// 1152, 900,
|
||||
// 1440, 900,
|
||||
1600, 900,
|
||||
// 1280, 960,
|
||||
1440, 960,
|
||||
// 1280, 1024,
|
||||
// 1400, 1050,
|
||||
// 1680, 1050,
|
||||
// 1440, 1080,
|
||||
// 1920, 1080,
|
||||
// 2048, 1080,
|
||||
// 2880, 1080,
|
||||
3840, 1080,
|
||||
// 1600, 1200,
|
||||
1920, 1200,
|
||||
// 1920, 1280,
|
||||
2560, 1440,
|
||||
// 3840, 1440,
|
||||
// 5120, 1440,
|
||||
// 2048, 1536,
|
||||
2560, 1600,
|
||||
// 2880, 1620,
|
||||
// 2880, 1800,
|
||||
3200, 1800,
|
||||
// 2560, 2048,
|
||||
// 3840, 2160,
|
||||
4096, 2160,
|
||||
// 5120, 2160,
|
||||
5120, 2880,
|
||||
6016, 3384,
|
||||
// 7680, 4320,
|
||||
8192, 4320,
|
||||
|
||||
// one day... we may have to add more resolutions here. when that day comes...
|
||||
// we'll do that. until then... I think 8k is "good enough"
|
||||
0, 0 // sentinel
|
||||
};
|
||||
// when we have more res's above bump this to be that + 1 at a minimum
|
||||
#define MAX_RES_NUM 20
|
||||
|
||||
#define ETC1 -1
|
||||
#define ETC2 -2
|
||||
|
||||
static Evas_Object *win = NULL, *subwin = NULL, *image = NULL, *rend = NULL;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int from_w, from_h, to_w, to_h;
|
||||
Eina_Bool last : 1;
|
||||
} Mip;
|
||||
|
||||
static Mip *
|
||||
_resolutions_calc(int w, int h)
|
||||
{
|
||||
int i, j = 0;
|
||||
int nw, nh, pw = 0, ph = 0;
|
||||
Mip *mips = calloc(1, sizeof(Mip) * MAX_RES_NUM);
|
||||
|
||||
if (!mips) return NULL;
|
||||
for (i = 0; resolutions[i]; i += 2)
|
||||
{
|
||||
nh = resolutions[i + 1];
|
||||
nw = (w * nh) / h;
|
||||
if ((nh >= h) || (nw >= w))
|
||||
{
|
||||
mips[j].from_w = pw;
|
||||
mips[j].from_h = ph;
|
||||
mips[j].to_w = 1000000000;
|
||||
mips[j].to_h = 1000000000;
|
||||
mips[j].last = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
mips[j].from_w = pw;
|
||||
mips[j].from_h = ph;
|
||||
mips[j].to_w = nw;
|
||||
mips[j].to_h = nh;
|
||||
|
||||
j++;
|
||||
pw = nw + 1;
|
||||
ph = nh + 1;
|
||||
}
|
||||
return mips;
|
||||
}
|
||||
|
||||
EAPI int
|
||||
elm_main(int argc, char **argv)
|
||||
{
|
||||
const char *edje_cc, *mode, *file, *outfile;
|
||||
int bg_r = 64;
|
||||
int bg_g = 64;
|
||||
int bg_b = 64;
|
||||
char dir_buf[128], img_buf[256], edc_buf[256], cmd_buf[1024], qual_buf[64];
|
||||
const char *dir, *quality_string = NULL, *img_name = NULL;
|
||||
Mip *mips = NULL;
|
||||
int i, imw, imh, w, h, quality;
|
||||
int ret = 0, mips_num = 0;
|
||||
Eina_Bool alpha;
|
||||
FILE *f;
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
printf("USAGE: enlightenment_wallpaper_gen EDJE FILL INPUT OUT QUALITY [R G B]\n"
|
||||
"\n"
|
||||
" EDJE is edje_cc command to use (full path or in $PATH)\n"
|
||||
" FILL is one of:\n"
|
||||
" stretch\n"
|
||||
" tile\n"
|
||||
" center (requires R G B)\n"
|
||||
" scale_in (requires R G B)\n"
|
||||
" scale_out\n"
|
||||
" pan\n"
|
||||
" INPUT is some image file to put into the wallpaper edj\n"
|
||||
" OUT is the paht/location of the wallpaper edj output\n"
|
||||
" QUALITY is:\n"
|
||||
" 0-100 (0-99 is lossy, 100 is lossless compression)\n"
|
||||
" etc1\n"
|
||||
" etc2\n"
|
||||
" R, G, B are Red, Green and Blue values 0 to 255\n"
|
||||
"\n"
|
||||
" e.g.\n"
|
||||
" enlightenment_wallpaper_gen edje_cc scale_out cat.jpg wallpaper.edj 80\n"
|
||||
" enlightenment_wallpaper_gen edje_cc center mylogo.png wallpaper.edj 100 48 64 64\n"
|
||||
" enlightenment_wallpaper_gen /usr/local/bin/edje_cc tile pattern.jpg wallpaper.edj 98\n"
|
||||
" enlightenment_wallpaper_gen /opt/e/bin/edje_cc scale_out hugeimg.jpg wallpaper.edj etc1\n"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
elm_config_preferred_engine_set("buffer");
|
||||
win = elm_win_add(NULL, "Wallpaper-Gen", ELM_WIN_BASIC);
|
||||
elm_win_norender_push(win);
|
||||
evas_object_show(win);
|
||||
|
||||
subwin = elm_win_add(win, "inlined", ELM_WIN_INLINED_IMAGE);
|
||||
rend = elm_win_inlined_image_object_get(subwin);
|
||||
elm_win_norender_push(subwin);
|
||||
evas_object_show(subwin);
|
||||
|
||||
if (argc < 6) return 2;
|
||||
edje_cc = argv[1];
|
||||
mode = argv[2];
|
||||
file = argv[3];
|
||||
outfile = argv[4];
|
||||
if (!strcmp(argv[5], "etc1")) quality = ETC1;
|
||||
else if (!strcmp(argv[5], "etc2")) quality = ETC2;
|
||||
else
|
||||
{
|
||||
quality = atoi(argv[5]);
|
||||
if (quality < 0) quality = 0;
|
||||
else if (quality > 100) quality = 100;
|
||||
}
|
||||
|
||||
image = evas_object_image_filled_add(evas_object_evas_get(subwin));
|
||||
evas_object_image_file_set(image, file, NULL);
|
||||
evas_object_image_size_get(image, &w, &h);
|
||||
if ((w <= 0) || (h <= 0)) return 3;
|
||||
alpha = evas_object_image_alpha_get(image);
|
||||
elm_win_alpha_set(subwin, alpha);
|
||||
evas_object_show(image);
|
||||
|
||||
snprintf(dir_buf, sizeof(dir_buf), "/tmp/e_bg-XXXXXX");
|
||||
dir = mkdtemp(dir_buf);
|
||||
if (!dir) return 4;
|
||||
|
||||
if ((!strcmp(mode, "center")) ||
|
||||
(!strcmp(mode, "scale_in")))
|
||||
{ // need backing rgb color here
|
||||
if (argc < 9) return 5;
|
||||
bg_r = atoi(argv[6]);
|
||||
bg_g = atoi(argv[7]);
|
||||
bg_b = atoi(argv[8]);
|
||||
}
|
||||
if ((!strcmp(mode, "stretch")) ||
|
||||
(!strcmp(mode, "scale_in")) ||
|
||||
(!strcmp(mode, "scale_out")) ||
|
||||
(!strcmp(mode, "pan")))
|
||||
{ // need to produce multiple scaled versions
|
||||
mips = _resolutions_calc(w, h);
|
||||
if (!mips) return 6;
|
||||
for (i = 0; mips[i].to_w; i++)
|
||||
{
|
||||
mips_num++;
|
||||
if (mips[i].last)
|
||||
{
|
||||
imw = w;
|
||||
imh = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
imw = mips[i].to_w;
|
||||
imh = mips[i].to_h;
|
||||
}
|
||||
evas_object_resize(subwin, imw, imh);
|
||||
evas_object_resize(image, imw, imh);
|
||||
elm_win_render(subwin);
|
||||
if (mips[i].last)
|
||||
snprintf(img_buf, sizeof(img_buf), "%s/img.png",
|
||||
dir);
|
||||
else
|
||||
snprintf(img_buf, sizeof(img_buf), "%s/img-%ix%i.png",
|
||||
dir, imw, imh);
|
||||
if (!evas_object_image_save(rend, img_buf, NULL, "compress=0"))
|
||||
{
|
||||
ret = 7;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
// no multiple resolutions -0 save out original
|
||||
if (!mips)
|
||||
{
|
||||
evas_object_resize(subwin, w, h);
|
||||
evas_object_resize(image, w, h);
|
||||
elm_win_render(subwin);
|
||||
snprintf(img_buf, sizeof(img_buf), "%s/img.png", dir);
|
||||
if (!evas_object_image_save(rend, img_buf, NULL, "compress=0"))
|
||||
{
|
||||
ret = 8;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if ((quality == ETC1) && (alpha)) quality = ETC2; // etc1 -> etc2 if alpha
|
||||
if (quality == 100) quality_string = "COMP";
|
||||
else
|
||||
{
|
||||
if (quality == ETC1) quality_string = "LOSSY_ETC1";
|
||||
else if (quality == ETC2) quality_string = "LOSSY_ETC2";
|
||||
else
|
||||
{
|
||||
snprintf(qual_buf, sizeof(qual_buf), "LOSSY %i", quality);
|
||||
quality_string = qual_buf;
|
||||
}
|
||||
}
|
||||
// generate edc
|
||||
snprintf(edc_buf, sizeof(edc_buf), "%s/bg.edc", dir);
|
||||
f = fopen(edc_buf, "w");
|
||||
if (!f) goto cleanup;
|
||||
if ((mips) && (mips_num > 1))
|
||||
{
|
||||
fprintf(f,
|
||||
"images {\n"
|
||||
" set { name: \"img\";\n");
|
||||
for (i = mips_num - 1; i >= 0; i--)
|
||||
{
|
||||
fprintf(f,
|
||||
" image {\n");
|
||||
if (mips[i].last)
|
||||
{
|
||||
imw = w;
|
||||
imh = h;
|
||||
fprintf(f,
|
||||
" image: \"img.png\" %s;\n",
|
||||
quality_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
imw = mips[i].to_w;
|
||||
imh = mips[i].to_h;
|
||||
fprintf(f,
|
||||
" image: \"img-%ix%i.png\" %s;\n",
|
||||
imw, imh, quality_string);
|
||||
}
|
||||
fprintf(f,
|
||||
" size: %i %i %i %i;\n"
|
||||
" }\n",
|
||||
mips[i].from_w, mips[i].from_h,
|
||||
mips[i].to_w, mips[i].to_h);
|
||||
}
|
||||
fprintf(f,
|
||||
" }\n"
|
||||
"}\n");
|
||||
img_name = "img";
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(f, "images.image: \"img.png\" %s;\n", quality_string);
|
||||
img_name = "img.png";
|
||||
}
|
||||
fprintf(f,
|
||||
"collections {\n"
|
||||
" group { name: \"e/desktop/background\";\n"
|
||||
" data.item: \"noanimation\" \"1\";\n");
|
||||
if (!strcmp(mode, "stretch"))
|
||||
{
|
||||
fprintf(f, " data { item: \"style\" \"0\"; }\n");
|
||||
fprintf(f,
|
||||
" parts {\n"
|
||||
" part { name: \"bg\"; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" image {\n"
|
||||
" normal: \"%s\";\n"
|
||||
" scale_hint: STATIC;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
, img_name);
|
||||
}
|
||||
else if (!strcmp(mode, "tile"))
|
||||
{
|
||||
fprintf(f, " data { item: \"style\" \"1\"; }\n");
|
||||
fprintf(f,
|
||||
" parts {\n"
|
||||
" part { name: \"bg\"; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" image {\n"
|
||||
" normal: \"%s\";\n"
|
||||
" }\n"
|
||||
" fill.size.relative: 0 0;\n"
|
||||
" fill.size.offset: %i %i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
, img_name, w, h);
|
||||
}
|
||||
else if (!strcmp(mode, "center"))
|
||||
{
|
||||
fprintf(f, " data { item: \"style\" \"2\"; }\n");
|
||||
fprintf(f,
|
||||
" parts {\n"
|
||||
" part { name: \"col\"; type: RECT; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" color: %i %i %i 255;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" part { name: \"bg\"; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" image {\n"
|
||||
" normal: \"%s\";\n"
|
||||
" }\n"
|
||||
" min: %i %i; max: %i %i;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
, bg_r, bg_g, bg_b, img_name, w, h, w, h);
|
||||
}
|
||||
else if (!strcmp(mode, "scale_in"))
|
||||
{
|
||||
fprintf(f, " data { item: \"style\" \"3\"; }\n");
|
||||
fprintf(f,
|
||||
" parts {\n"
|
||||
" part { name: \"col\"; type: RECT; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" color: %i %i %i 255;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" part { name: \"bg\"; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" image {\n"
|
||||
" normal: \"%s\";\n"
|
||||
" scale_hint: STATIC;\n"
|
||||
" }\n"
|
||||
" aspect: (%i/%i) (%i/%i); aspect_preference: BOTH;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
, bg_r, bg_g, bg_b, img_name, w, h, w, h);
|
||||
}
|
||||
else if (!strcmp(mode, "scale_out"))
|
||||
{
|
||||
fprintf(f, " data { item: \"style\" \"4\"; }\n");
|
||||
fprintf(f,
|
||||
" parts {\n"
|
||||
" part { name: \"bg\"; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0;\n"
|
||||
" image {\n"
|
||||
" normal: \"%s\";\n"
|
||||
" scale_hint: STATIC;\n"
|
||||
" }\n"
|
||||
" aspect: (%i/%i) (%i/%i); aspect_preference: NONE;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
, img_name, w, h, w, h);
|
||||
}
|
||||
else if (!strcmp(mode, "pan"))
|
||||
{
|
||||
fprintf(f, " data { item: \"style\" \"5\"; }\n");
|
||||
fprintf(f,
|
||||
" script {\n"
|
||||
" public cur_anim; public cur_x; public cur_y;\n"
|
||||
" public prev_x; public prev_y;\n"
|
||||
" public total_x; public total_y;\n"
|
||||
" public pan_bg(val, Float:v) {\n"
|
||||
" new Float:x, Float:y, Float:px, Float: py;\n"
|
||||
" px = get_float(prev_x);\n"
|
||||
" py = get_float(prev_y);\n"
|
||||
" if (get_int(total_x) > 1) {\n"
|
||||
" x = float(get_int(cur_x)) / (get_int(total_x) - 1);\n"
|
||||
" x = px - (px - x) * v;\n"
|
||||
" } else {\n"
|
||||
" x = 0.0;\n"
|
||||
" v = 1.0;\n"
|
||||
" }\n"
|
||||
" if (get_int(total_y) > 1) {\n"
|
||||
" y = float(get_int(cur_y)) / (get_int(total_y) - 1);\n"
|
||||
" y = py - (py - y) * v;\n"
|
||||
" } else {\n"
|
||||
" y = 0.0;\n"
|
||||
" v = 1.0; }\n"
|
||||
" set_state_val(PART:\"bg\", STATE_ALIGNMENT, x, y);\n"
|
||||
" if (v >= 1.0) {\n"
|
||||
" set_int(cur_anim, 0);\n"
|
||||
" set_float(prev_x, x);\n"
|
||||
" set_float(prev_y, y);\n"
|
||||
" return 0;\n"
|
||||
" }\n"
|
||||
" return 1;\n"
|
||||
" }\n"
|
||||
" public message(Msg_Type:type, id, ...) {\n"
|
||||
" if ((type == MSG_FLOAT_SET) && (id == 0)) {\n"
|
||||
" new ani;\n"
|
||||
" get_state_val(PART:\"bg\", STATE_ALIGNMENT, prev_x, prev_y);\n"
|
||||
" set_int(cur_x, round(getfarg(3)));\n"
|
||||
" set_int(total_x, round(getfarg(4)));\n"
|
||||
" set_int(cur_y, round(getfarg(5)));\n"
|
||||
" set_int(total_y, round(getfarg(6)));\n"
|
||||
" ani = get_int(cur_anim);\n"
|
||||
" if (ani > 0) cancel_anim(ani);\n"
|
||||
" ani = anim(getfarg(2), \"pan_bg\", 0);\n"
|
||||
" set_int(cur_anim, ani);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" parts {\n"
|
||||
" part { name: \"bg\"; mouse_events: 0;\n"
|
||||
" description { state: \"default\" 0.0;\n"
|
||||
" image {\n"
|
||||
" normal: \"%s\";\n"
|
||||
" scale_hint: STATIC;\n"
|
||||
" }\n"
|
||||
" aspect: (%i/%i) (%i/%i); aspect_preference: NONE;\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" program {\n"
|
||||
" signal: \"load\"; source: \"\";\n"
|
||||
" script {\n"
|
||||
" custom_state(PART:\"bg\", \"default\", 0.0);\n"
|
||||
" set_state(PART:\"bg\", \"custom\", 0.0);\n"
|
||||
" set_float(prev_x, 0.0);\n"
|
||||
" set_float(prev_y, 0.0);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
, img_name, w, h, w, h);
|
||||
}
|
||||
fprintf(f,
|
||||
" }\n"
|
||||
"}\n");
|
||||
fclose(f);
|
||||
free(mips);
|
||||
if (snprintf(cmd_buf, sizeof(cmd_buf),
|
||||
"%s -fastdecomp -id %s -fd %s -sd %s -vd %s -dd %s -md %s "
|
||||
"%s/bg.edc %s",
|
||||
edje_cc, dir, dir, dir, dir, dir, dir,
|
||||
dir, outfile) >= (int)sizeof(cmd_buf))
|
||||
{
|
||||
ret = 9;
|
||||
goto cleanup;
|
||||
}
|
||||
ret = system(cmd_buf);
|
||||
cleanup:
|
||||
ecore_file_recursive_rm(dir);
|
||||
evas_object_del(win);
|
||||
return ret;
|
||||
}
|
||||
ELM_MAIN()
|
|
@ -513,10 +513,10 @@ executable('enlightenment_elm_cfgtool',
|
|||
install : true
|
||||
)
|
||||
|
||||
executable('enlightenment_static_grabber',
|
||||
[ 'e_static_grab.c' ],
|
||||
executable('enlightenment_wallpaper_gen',
|
||||
[ 'e_wallpaper_gen_main.c' ],
|
||||
include_directories: include_directories('../..'),
|
||||
dependencies : [ dep_eina, dep_eet ],
|
||||
dependencies : [ dep_elementary ],
|
||||
install_dir : dir_e_utils,
|
||||
install : true
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue