UI: SVG Thumbnails
Allow SVG files to have previews in the File Browser. Adds nanosvgrast.h to extern\nanosvg\, which is an SVG rasterizer that is an optional part of the nanosvg source. Pull Request: https://projects.blender.org/blender/blender/pulls/109567
This commit is contained in:
parent
aa700821a8
commit
565436bf5f
1
extern/CMakeLists.txt
vendored
1
extern/CMakeLists.txt
vendored
@ -22,6 +22,7 @@ endif()
|
||||
|
||||
|
||||
add_subdirectory(rangetree)
|
||||
add_subdirectory(nanosvg)
|
||||
add_subdirectory(wcwidth)
|
||||
|
||||
if(WITH_BULLET)
|
||||
|
21
extern/nanosvg/CMakeLists.txt
vendored
Normal file
21
extern/nanosvg/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# SPDX-FileCopyrightText: 2002-2022 Blender Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
PUBLIC .
|
||||
../../source/blender/blenlib
|
||||
)
|
||||
|
||||
set(SRC
|
||||
nanosvg.h
|
||||
nanosvgrast.h
|
||||
blender_nanosvg.c
|
||||
blender_raster.c
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
blender_add_lib(extern_nanosvg "${SRC}" "${INC}" "" "${LIB}")
|
||||
add_library(bf::extern::nanosvg ALIAS extern_nanosvg)
|
10
extern/nanosvg/blender_nanosvg.c
vendored
Normal file
10
extern/nanosvg/blender_nanosvg.c
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#define NANOSVG_IMPLEMENTATION
|
||||
#define NANOSVG_ALL_COLOR_KEYWORDS
|
||||
|
||||
#include <stdio.h>
|
||||
#include "BLI_utildefines.h"
|
||||
#include "nanosvg.h"
|
6
extern/nanosvg/blender_raster.c
vendored
Normal file
6
extern/nanosvg/blender_raster.c
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#define NANOSVGRAST_IMPLEMENTATION
|
||||
#include "nanosvgrast.h"
|
1458
extern/nanosvg/nanosvgrast.h
vendored
Normal file
1458
extern/nanosvg/nanosvgrast.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1504,7 +1504,7 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
|
||||
// printf("%s: %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
|
||||
BLI_assert(preview->flags &
|
||||
(FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER |
|
||||
FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB));
|
||||
FILE_TYPE_OBJECT_IO | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB));
|
||||
|
||||
if (preview->flags & FILE_TYPE_IMAGE) {
|
||||
source = THB_SOURCE_IMAGE;
|
||||
@ -1519,6 +1519,9 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
|
||||
else if (preview->flags & FILE_TYPE_FTFONT) {
|
||||
source = THB_SOURCE_FONT;
|
||||
}
|
||||
else if (preview->flags & FILE_TYPE_OBJECT_IO) {
|
||||
source = THB_SOURCE_OBJECT_IO;
|
||||
}
|
||||
|
||||
IMB_thumb_path_lock(preview->filepath);
|
||||
/* Always generate biggest preview size for now, it's simpler and avoids having to re-generate
|
||||
@ -1620,7 +1623,8 @@ static void filelist_cache_previews_push(FileList *filelist, FileDirEntry *entry
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(entry->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT |
|
||||
if (!(entry->typeflag &
|
||||
(FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_OBJECT_IO |
|
||||
FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP | FILE_TYPE_BLENDERLIB)))
|
||||
{
|
||||
return;
|
||||
|
@ -30,6 +30,7 @@ set(SRC
|
||||
intern/format_hdr.cc
|
||||
intern/format_png.cc
|
||||
intern/format_psd.cc
|
||||
intern/format_svg.cc
|
||||
intern/format_targa.cc
|
||||
intern/format_tiff.cc
|
||||
intern/imageprocess.cc
|
||||
@ -80,6 +81,7 @@ set(LIB
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_intern_memutil
|
||||
bf_intern_opencolorio
|
||||
PRIVATE bf::extern::nanosvg
|
||||
|
||||
${JPEG_LIBRARIES}
|
||||
)
|
||||
|
@ -31,6 +31,7 @@ typedef enum ThumbSource {
|
||||
THB_SOURCE_MOVIE,
|
||||
THB_SOURCE_BLEND,
|
||||
THB_SOURCE_FONT,
|
||||
THB_SOURCE_OBJECT_IO,
|
||||
} ThumbSource;
|
||||
|
||||
/**
|
||||
|
@ -290,6 +290,19 @@ struct ImBuf *imb_load_psd(const unsigned char *mem,
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Format: SVG - Only for thumbnails.
|
||||
* \{ */
|
||||
|
||||
struct ImBuf *imb_load_filepath_thumbnail_svg(const char *filepath,
|
||||
const int flags,
|
||||
const size_t max_thumb_size,
|
||||
char colorspace[],
|
||||
size_t *r_width,
|
||||
size_t *r_height);
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
@ -199,6 +199,22 @@ const ImFileType IMB_FILE_TYPES[] = {
|
||||
/*default_save_role*/ COLOR_ROLE_DEFAULT_BYTE,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
/* Only implementing thumbnailing for SVG file type to support specialized importers.
|
||||
* General file loading, if wanted, would require a better library and would have to
|
||||
* support features like user-specified resolution. */
|
||||
|
||||
/*init*/ nullptr,
|
||||
/*exit*/ nullptr,
|
||||
/*is_a*/ nullptr,
|
||||
/*load*/ nullptr,
|
||||
/*load_filepath*/ nullptr,
|
||||
/*load_filepath_thumbnail*/ imb_load_filepath_thumbnail_svg,
|
||||
/*save*/ nullptr,
|
||||
/*flag*/ 0,
|
||||
/*filetype*/ IMB_FTYPE_NONE,
|
||||
/*default_save_role*/ COLOR_ROLE_DEFAULT_BYTE,
|
||||
},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0, 0, 0},
|
||||
};
|
||||
|
||||
|
66
source/blender/imbuf/intern/format_svg.cc
Normal file
66
source/blender/imbuf/intern/format_svg.cc
Normal file
@ -0,0 +1,66 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup imbuf
|
||||
*
|
||||
* SVG vector graphics format support for the purpose of thumbnail-display.
|
||||
* While loading these as an #ImBuf is trivial to support, it would expose
|
||||
* limitations of NANOSVG and users may end up needing more advanced options
|
||||
* specific to loading vector graphics (such as resolution control), see #109567 for details.
|
||||
*/
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_filetype.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "nanosvg.h"
|
||||
#include "nanosvgrast.h"
|
||||
|
||||
ImBuf *imb_load_filepath_thumbnail_svg(const char *filepath,
|
||||
const int /* flags */,
|
||||
const size_t max_thumb_size,
|
||||
char colorspace[],
|
||||
size_t *r_width,
|
||||
size_t *r_height)
|
||||
{
|
||||
NSVGimage *image = nsvgParseFromFile(filepath, "px", 96.0f);
|
||||
|
||||
if (image == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (image->width == 0 || image->height == 0) {
|
||||
nsvgDelete(image);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int w = int(image->width);
|
||||
int h = int(image->height);
|
||||
|
||||
/* Return full size of the image. */
|
||||
*r_width = size_t(w);
|
||||
*r_height = size_t(h);
|
||||
|
||||
NSVGrasterizer *rast = nsvgCreateRasterizer();
|
||||
if (rast == nullptr) {
|
||||
nsvgDelete(image);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
|
||||
|
||||
const float scale = float(max_thumb_size) / MAX2(w, h);
|
||||
const int dest_w = MAX2(int(w * scale), 1);
|
||||
const int dest_h = MAX2(int(h * scale), 1);
|
||||
|
||||
ImBuf *ibuf = IMB_allocImBuf(dest_w, dest_h, 32, IB_rect);
|
||||
if (ibuf != nullptr) {
|
||||
nsvgRasterize(rast, image, 0, 0, scale, ibuf->byte_buffer.data, dest_w, dest_h, dest_w * 4);
|
||||
nsvgDeleteRasterizer(rast);
|
||||
nsvgDelete(image);
|
||||
IMB_flipy(ibuf);
|
||||
}
|
||||
|
||||
return ibuf;
|
||||
}
|
@ -361,7 +361,8 @@ static ImBuf *thumb_create_ex(const char *file_path,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) {
|
||||
if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT, THB_SOURCE_OBJECT_IO))
|
||||
{
|
||||
/* only load if we didn't give an image */
|
||||
if (img == nullptr) {
|
||||
switch (source) {
|
||||
@ -374,6 +375,12 @@ static ImBuf *thumb_create_ex(const char *file_path,
|
||||
case THB_SOURCE_FONT:
|
||||
img = IMB_thumb_load_font(file_path, tsize, tsize);
|
||||
break;
|
||||
case THB_SOURCE_OBJECT_IO: {
|
||||
if (BLI_path_extension_check(file_path, ".svg")) {
|
||||
img = IMB_thumb_load_image(file_path, tsize, nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLI_assert_unreachable(); /* This should never happen */
|
||||
}
|
||||
|
@ -9,11 +9,12 @@ set(INC
|
||||
../../bmesh
|
||||
../../depsgraph
|
||||
../../editors/include
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/clog
|
||||
../../../../intern/guardedalloc
|
||||
../../../../intern/utfconv
|
||||
../../../../extern/nanosvg
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
@ -30,15 +31,13 @@ set(SRC
|
||||
intern/gpencil_io_export_base.hh
|
||||
intern/gpencil_io_import_base.hh
|
||||
intern/gpencil_io_import_svg.hh
|
||||
|
||||
# Only so this file is known by CMake.
|
||||
../../../../extern/nanosvg/nanosvg.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
PRIVATE bf::blenkernel
|
||||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::extern::nanosvg
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
bf_io_common
|
||||
)
|
||||
|
@ -23,10 +23,6 @@
|
||||
#include "gpencil_io.h"
|
||||
#include "gpencil_io_import_svg.hh"
|
||||
|
||||
/* Custom flags for NanoSVG. */
|
||||
#define NANOSVG_ALL_COLOR_KEYWORDS
|
||||
#define NANOSVG_IMPLEMENTATION
|
||||
|
||||
#include "nanosvg.h"
|
||||
|
||||
using blender::MutableSpan;
|
||||
|
@ -112,6 +112,9 @@ static PyObject *bpy_utils_previews_load(PyObject *UNUSED(self), PyObject *args)
|
||||
else if (STREQ(path_type_s, "FONT")) {
|
||||
path_type = THB_SOURCE_FONT;
|
||||
}
|
||||
else if (STREQ(path_type_s, "OBJECT_IO")) {
|
||||
path_type = THB_SOURCE_OBJECT_IO;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"load: invalid '%s' filetype, only [" STR_SOURCE_TYPES
|
||||
|
Loading…
Reference in New Issue
Block a user