diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-04-23 21:16:32 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-04-23 21:24:49 +0300 |
commit | 1287fa3f7c5a0dc4484aa7e94267d21cc8b0b1f0 (patch) | |
tree | 20ab632c21b31b5994481978a2e8f1d8d44f0558 /source/blender | |
parent | 20105fc8454a34c342f0f5500497c4452ec2b7ee (diff) |
UI: option to load icon from file
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_icons.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/icons.c | 97 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app_icons.c | 47 |
3 files changed, 128 insertions, 24 deletions
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index fb40e5be281..ffcbd231524 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -65,8 +65,11 @@ struct Icon { struct Icon_Geom { int icon_id; int coords_len; + int coords_range[2]; const unsigned char (*coords)[2]; const unsigned char (*colors)[4]; + /* when not NULL, the memory of coords and colors is a sub-region of this pointer. */ + const void *mem; }; typedef struct Icon Icon; @@ -84,8 +87,6 @@ int BKE_icon_id_ensure(struct ID *id); int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview); -int BKE_icon_geom_ensure(struct Icon_Geom *geom); - /* retrieve icon for id */ struct Icon *BKE_icon_get(const int icon_id); @@ -149,6 +150,9 @@ struct PreviewImage *BKE_previewimg_cached_thumbnail_read( void BKE_previewimg_cached_release(const char *name); void BKE_previewimg_cached_release_pointer(struct PreviewImage *prv); +int BKE_icon_geom_ensure(struct Icon_Geom *geom); +struct Icon_Geom *BKE_icon_geom_from_file(const char *filename); + struct ImBuf *BKE_icon_geom_rasterize( const struct Icon_Geom *geom, const unsigned int size_x, const unsigned int size_y); diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index 7097b349125..e47d6761690 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -51,6 +51,7 @@ #include "BLI_ghash.h" #include "BLI_linklist_lockfree.h" #include "BLI_string.h" +#include "BLI_fileops.h" #include "BLI_threads.h" #include "BKE_icons.h" @@ -96,8 +97,14 @@ static void icon_free(void *val) if (icon) { if (icon->obj_type == ICON_DATA_GEOM) { struct Icon_Geom *obj = icon->obj; - MEM_freeN((void *)obj->coords); - MEM_freeN((void *)obj->colors); + if (obj->mem) { + /* coords & colors are part of this memory. */ + MEM_freeN((void *)obj->mem); + } + else { + MEM_freeN((void *)obj->coords); + MEM_freeN((void *)obj->colors); + } MEM_freeN(icon->obj); } @@ -621,22 +628,6 @@ int BKE_icon_preview_ensure(ID *id, PreviewImage *preview) return preview->icon_id; } -int BKE_icon_geom_ensure(struct Icon_Geom *geom) -{ - BLI_assert(BLI_thread_is_main()); - - if (geom->icon_id) { - return geom->icon_id; - } - - geom->icon_id = get_next_free_id(); - - icon_create(geom->icon_id, ICON_DATA_GEOM, geom); - /* Not managed for now, we may want this to be configurable per icon). */ - - return geom->icon_id; -} - Icon *BKE_icon_get(const int icon_id) { BLI_assert(BLI_thread_is_main()); @@ -735,3 +726,73 @@ bool BKE_icon_delete_unmanaged(const int icon_id) return false; } } + +/* -------------------------------------------------------------------- */ +/** \name Geometry Icon + * \{ */ + +int BKE_icon_geom_ensure(struct Icon_Geom *geom) +{ + BLI_assert(BLI_thread_is_main()); + + if (geom->icon_id) { + return geom->icon_id; + } + + geom->icon_id = get_next_free_id(); + + icon_create(geom->icon_id, ICON_DATA_GEOM, geom); + /* Not managed for now, we may want this to be configurable per icon). */ + + return geom->icon_id; +} + +struct Icon_Geom *BKE_icon_geom_from_memory(const uchar *data, size_t data_len) +{ + BLI_assert(BLI_thread_is_main()); + if (data_len <= 8) { + goto fail; + } + const int div = 3 * 2 * 3; + const int coords_len = (data_len - 8) / div; + if (coords_len * div != data_len) { + goto fail; + } + + const uchar header[4] = {'V', 'C', 'O', 0}; + const uchar *p = data; + if (memcmp(p, header, ARRAY_SIZE(header)) != 0) { + goto fail; + } + p += 4; + + struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__); + geom->coords_range[0] = (int)*p++; + geom->coords_range[1] = (int)*p++; + /* x, y ignored for now */ + p += 2; + + geom->coords_len = coords_len; + geom->coords = (const void *)p; + geom->colors = (const void *)(p + (data_len / 3)); + geom->icon_id = 0; + geom->mem = data; + return geom; + +fail: + MEM_freeN((void *)data); + return NULL; +} + +struct Icon_Geom *BKE_icon_geom_from_file(const char *filename) +{ + BLI_assert(BLI_thread_is_main()); + size_t data_len; + uchar *data = BLI_file_read_binary_as_mem(filename, 0, &data_len); + if (data == NULL) { + return NULL; + } + return BKE_icon_geom_from_memory(data, data_len); +} + +/** \} */ diff --git a/source/blender/python/intern/bpy_app_icons.c b/source/blender/python/intern/bpy_app_icons.c index 8aeee1aff9c..6d3b50d5688 100644 --- a/source/blender/python/intern/bpy_app_icons.c +++ b/source/blender/python/intern/bpy_app_icons.c @@ -38,22 +38,28 @@ /* We may want to load direct from file. */ PyDoc_STRVAR(bpy_app_icons_new_triangles_doc, -".. function:: new_triangles(coords, colors)" +".. function:: new_triangles(range, coords, colors)" "\n" " Create a new icon from triangle geometry.\n" "\n" +" :arg range: Pair of ints.\n" +" :type range: tuple.\n" " :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n" -" :type coords: byte sequence\n" +" :type coords: byte sequence.\n" " :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n" -" :type colors: byte sequence\n" +" :type colors: byte sequence.\n" " :return: Unique icon value (pass to interface ``icon_value`` argument).\n" " :rtype: int\n" ); static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *args) { /* bytes */ + uchar coords_range[2]; PyObject *py_coords, *py_colors; - if (!PyArg_ParseTuple(args, "SS:new_triangles", &py_coords, &py_colors)) { + if (!PyArg_ParseTuple( + args, "(BB)SS:new_triangles", + &coords_range[0], &coords_range[1], &py_coords, &py_colors)) + { return NULL; } @@ -78,6 +84,8 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__); geom->coords_len = tris_len; + geom->coords_range[0] = coords_range[0]; + geom->coords_range[1] = coords_range[1]; geom->coords = coords; geom->colors = colors; geom->icon_id = 0; @@ -85,6 +93,36 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a return PyLong_FromLong(icon_id); } +PyDoc_STRVAR(bpy_app_icons_new_triangles_from_file_doc, +".. function:: new_triangles_from_file(filename)" +"\n" +" Create a new icon from triangle geometry.\n" +"\n" +" :arg range: File path.\n" +" :type range: string.\n" +" :return: Unique icon value (pass to interface ``icon_value`` argument).\n" +" :rtype: int\n" +); +static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), PyObject *args) +{ + /* bytes */ + char *filename; + if (!PyArg_ParseTuple( + args, "s:new_triangles_from_file", + &filename)) + { + return NULL; + } + + struct Icon_Geom *geom = BKE_icon_geom_from_file(filename); + if (geom == NULL) { + PyErr_SetString(PyExc_ValueError, "Unable to load from file"); + return NULL; + } + int icon_id = BKE_icon_geom_ensure(geom); + return PyLong_FromLong(icon_id); +} + PyDoc_STRVAR(bpy_app_icons_release_doc, ".. function:: release(icon_id)" "\n" @@ -110,6 +148,7 @@ static PyObject *bpy_app_icons_release(PyObject *UNUSED(self), PyObject *args) static struct PyMethodDef M_AppIcons_methods[] = { {"new_triangles", (PyCFunction)bpy_app_icons_new_triangles, METH_VARARGS, bpy_app_icons_new_triangles_doc}, + {"new_triangles_from_file", (PyCFunction)bpy_app_icons_new_triangles_from_file, METH_VARARGS, bpy_app_icons_new_triangles_from_file_doc}, {"release", (PyCFunction)bpy_app_icons_release, METH_VARARGS, bpy_app_icons_release_doc}, {NULL, NULL, 0, NULL} }; |