From 8c539b0ab521d442d88c70243c04cbb9e40fe412 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Apr 2015 10:10:17 +1000 Subject: Font preview for file browser D1002 by @plasmasolutions, with own refactoring. Note, needed to do a bad-level call here (IMB -> BLF) Also can't use the BLF API directly because its not thread-safe. So keep the function isolated (blf_thumbs.c). --- source/blender/blenfont/BLF_api.h | 6 ++ source/blender/blenfont/CMakeLists.txt | 1 + source/blender/blenfont/intern/blf_thumbs.c | 104 ++++++++++++++++++++++++++ source/blender/editors/space_file/file_draw.c | 17 +++-- source/blender/editors/space_file/filelist.c | 7 +- source/blender/imbuf/CMakeLists.txt | 1 + source/blender/imbuf/IMB_thumbs.h | 8 +- source/blender/imbuf/intern/thumbs.c | 19 +++-- source/blender/imbuf/intern/thumbs_font.c | 73 ++++++++++++++++++ 9 files changed, 222 insertions(+), 14 deletions(-) create mode 100644 source/blender/blenfont/intern/blf_thumbs.c create mode 100644 source/blender/imbuf/intern/thumbs_font.c (limited to 'source/blender') diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 206345582b2..09734bd9754 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -186,6 +186,12 @@ char **BLF_dir_get(int *ndir) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); /* Free the data return by BLF_dir_get. */ void BLF_dir_free(char **dirs, int count) ATTR_NONNULL(); +/* blf_thumbs.c */ +void BLF_thumb_preview( + const char *filename, const char **draw_str, const unsigned char draw_str_lines, + const float font_color[4], const int font_size, + unsigned char *buf, int w, int h, int channels) ATTR_NONNULL(); + #ifdef DEBUG void BLF_state_print(int fontid); #endif diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index 392a9ede100..2f10c3580e0 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -47,6 +47,7 @@ set(SRC intern/blf_font.c intern/blf_glyph.c intern/blf_lang.c + intern/blf_thumbs.c intern/blf_translation.c intern/blf_util.c diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c new file mode 100644 index 00000000000..afda6a382f9 --- /dev/null +++ b/source/blender/blenfont/intern/blf_thumbs.c @@ -0,0 +1,104 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Thomas Beck + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenfont/intern/blf_thumbs.c + * \ingroup blf + * + * Utility function to generate font preview images. + * + * Isolate since this needs to be called by #ImBuf code (bad level call). + */ + +#include +#include +#include + +#include + +#include FT_FREETYPE_H + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" +#include "BLI_threads.h" + +#include "blf_internal.h" +#include "blf_internal_types.h" + +#include "BLF_api.h" + +#include "BLI_strict_flags.h" + +/** + * This function is used for generating thumbnail previews. + * + * \note called from a thread, so it bypasses the normal BLF_* api (which isn't thread-safe). + */ +void BLF_thumb_preview( + const char *filename, + const char **draw_str, const unsigned char draw_str_lines, + const float font_color[4], const int font_size, + unsigned char *buf, int w, int h, int channels) +{ + const unsigned int dpi = 72; + const int font_size_min = 6; + int font_size_curr; + /* shrink 1/th each line */ + int font_shrink = 4; + + FontBLF* font; + int i; + + /* Create a new blender font obj and fill it with default values */ + font = blf_font_new("thumb_font", filename); + if (!font) { + printf("Info: Can't load font '%s', no preview possible\n", filename); + return; + } + + /* Would be done via the BLF API, but we're not using a fontid here */ + font->buf_info.cbuf = buf; + font->buf_info.ch = channels; + font->buf_info.w = w; + font->buf_info.h = h; + + /* Always create the image with a white font, + * the caller can theme how it likes */ + memcpy(font->buf_info.col, font_color, sizeof(font->buf_info.col)); + font->pos[1] = (float)h; + + font_size_curr = font_size; + + for (i = 0; i < draw_str_lines; i++) { + blf_font_size(font, (unsigned int)MAX2(font_size_min, font_size_curr), dpi); + + /* decrease font size each time */ + font_size_curr -= (font_size_curr / font_shrink); + font_shrink += 1; + + font->pos[1] -= font->glyph_cache->ascender * 1.1f; + + blf_font_buffer(font, draw_str[i]); + } + + blf_font_free(font); +} diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 98c7ddeff77..a6f3a73841e 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -323,7 +323,7 @@ void file_calc_previews(const bContext *C, ARegion *ar) UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height); } -static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, bool dropshadow, bool drag) +static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, bool is_icon, bool drag) { uiBut *but; float fx, fy; @@ -332,6 +332,7 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int float scaledx, scaledy; float scale; int ex, ey; + bool use_dropshadow = !is_icon && (file->flags & FILE_TYPE_IMAGE); BLI_assert(imb != NULL); @@ -367,17 +368,23 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* shadow */ - if (dropshadow) + if (use_dropshadow) { UI_draw_box_shadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey)); + } glEnable(GL_BLEND); /* the image */ - glColor4f(1.0, 1.0, 1.0, 1.0); + if (!is_icon && file->flags & FILE_TYPE_FTFONT) { + UI_ThemeColor(TH_TEXT); + } + else { + glColor4f(1.0, 1.0, 1.0, 1.0); + } glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale); /* border */ - if (dropshadow) { + if (use_dropshadow) { glColor4f(0.0f, 0.0f, 0.0f, 0.4f); fdrawbox((float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey)); } @@ -549,7 +556,7 @@ void file_draw_list(const bContext *C, ARegion *ar) is_icon = 1; } - file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & FILE_TYPE_IMAGE), do_drag); + file_draw_preview(block, file, sx, sy, imb, layout, is_icon, do_drag); } else { file_draw_icon(block, file->path, sx, sy - (UI_UNIT_Y / 6), get_file_icon(file), ICON_DEFAULT_WIDTH_SCALE, ICON_DEFAULT_HEIGHT_SCALE, do_drag); diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 66acd7d05e3..5214b611fb9 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1348,6 +1348,9 @@ static void thumbnails_startjob(void *tjv, short *stop, short *do_update, float limg->flags |= FILE_TYPE_MOVIE_ICON; } } + else if (limg->flags & FILE_TYPE_FTFONT) { + limg->img = IMB_thumb_manage(limg->path, THB_NORMAL, THB_SOURCE_FONT); + } *do_update = true; PIL_sleep_ms(10); limg = limg->next; @@ -1363,7 +1366,7 @@ static void thumbnails_update(void *tjv) while (limg) { if (!limg->done && limg->img) { tj->filelist->filelist[limg->index].image = IMB_dupImBuf(limg->img); - /* update flag for movie files where thumbnail can't be created */ + /* update flag for movie and font files where thumbnail can't be created */ if (limg->flags & FILE_TYPE_MOVIE_ICON) { tj->filelist->filelist[limg->index].flags &= ~FILE_TYPE_MOVIE; tj->filelist->filelist[limg->index].flags |= FILE_TYPE_MOVIE_ICON; @@ -1408,7 +1411,7 @@ void thumbnails_start(FileList *filelist, const bContext *C) continue; } if (!filelist->filelist[idx].image) { - if (filelist->filelist[idx].flags & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | + if (filelist->filelist[idx].flags & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_FTFONT | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) { FileImage *limg = MEM_callocN(sizeof(*limg), __func__); diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index eadedbd5e00..bdd8230a6ff 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -66,6 +66,7 @@ set(SRC intern/targa.c intern/thumbs.c intern/thumbs_blend.c + intern/thumbs_font.c intern/util.c intern/writeimage.c diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h index bea531c1442..404052f2e8e 100644 --- a/source/blender/imbuf/IMB_thumbs.h +++ b/source/blender/imbuf/IMB_thumbs.h @@ -54,7 +54,8 @@ typedef enum ThumbSize { typedef enum ThumbSource { THB_SOURCE_IMAGE, THB_SOURCE_MOVIE, - THB_SOURCE_BLEND + THB_SOURCE_BLEND, + THB_SOURCE_FONT, } ThumbSource; /* don't generate thumbs for images bigger then this (100mb) */ @@ -79,6 +80,11 @@ void IMB_thumb_makedirs(void); ImBuf *IMB_thumb_load_blend(const char *path); void IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float aspect); +/* special function for previewing fonts */ +ImBuf *IMB_thumb_load_font( + const char *filename, + unsigned int x, unsigned int y); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index e88cbef206a..78f47b7bc34 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -330,15 +330,22 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im if (!img) return NULL; } else { - if (THB_SOURCE_IMAGE == source || THB_SOURCE_BLEND == source) { + if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) { /* only load if we didnt give an image */ if (img == NULL) { - if (THB_SOURCE_BLEND == source) { - img = IMB_thumb_load_blend(path); - } - else { - img = IMB_loadiffname(path, IB_rect | IB_metadata | IB_thumbnail, NULL); + switch (source) { + case THB_SOURCE_IMAGE: + img = IMB_loadiffname(path, IB_rect | IB_metadata, NULL); + break; + case THB_SOURCE_BLEND: + img = IMB_thumb_load_blend(path); + break; + case THB_SOURCE_FONT: + img = IMB_thumb_load_font(path, tsize, tsize); + break; + default: + BLI_assert(0); /* This should never happen */ } } diff --git a/source/blender/imbuf/intern/thumbs_font.c b/source/blender/imbuf/intern/thumbs_font.c new file mode 100644 index 00000000000..c8982318d80 --- /dev/null +++ b/source/blender/imbuf/intern/thumbs_font.c @@ -0,0 +1,73 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Thomas Beck. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/imbuf/intern/thumbs_font.c + * \ingroup imbuf + */ + +#include "BLI_utildefines.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_thumbs.h" + + +/* XXX, bad level call */ +#include "../../blenfont/BLF_api.h" + + +struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y) +{ + const int font_size = y / 4; + const char *thumb_str[] = { + "AaBbCc", + + "The quick", + "brown fox", + "jumps over", + "the lazy dog", + }; + + struct ImBuf *ibuf; + float font_color[4]; + + /* create a white image (theme color is used for drawing) */ + font_color[0] = font_color[1] = font_color[2] = 1.0f; + + /* fill with zero alpha */ + font_color[3] = 0.0f; + + ibuf = IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata); + IMB_rectfill(ibuf, font_color); + + /* draw with full alpha */ + font_color[3] = 1.0f; + + BLF_thumb_preview( + filename, thumb_str, ARRAY_SIZE(thumb_str), + font_color, font_size, + (unsigned char *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels); + + return ibuf; +} + -- cgit v1.2.3