Blender  V2.93
ed_draw.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "MEM_guardedalloc.h"
29 
30 #include "BLI_listbase.h"
31 #include "BLI_path_util.h"
32 #include "BLI_rect.h"
33 #include "BLI_string.h"
34 #include "BLI_utildefines.h"
35 
36 #include "BKE_context.h"
37 #include "BKE_image.h"
38 
39 #include "BLF_api.h"
40 
41 #include "IMB_imbuf_types.h"
42 #include "IMB_metadata.h"
43 
44 #include "ED_screen.h"
45 #include "ED_space_api.h"
46 #include "ED_util.h"
47 
48 #include "GPU_immediate.h"
49 #include "GPU_matrix.h"
50 #include "GPU_state.h"
51 
52 #include "UI_interface.h"
53 #include "UI_resources.h"
54 
55 #include "RNA_access.h"
56 #include "WM_api.h"
57 #include "WM_types.h"
58 
62 void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *region, void *arg_info)
63 {
64  wmWindow *win = CTX_wm_window(C);
65  const float *mval_src = (float *)arg_info;
66  const float mval_dst[2] = {
67  win->eventstate->x - region->winrct.xmin,
68  win->eventstate->y - region->winrct.ymin,
69  };
70 
71  const uint shdr_pos = GPU_vertformat_attr_add(
73 
74  GPU_line_width(1.0f);
75 
77 
78  float viewport_size[4];
79  GPU_viewport_size_get_f(viewport_size);
80  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
81 
82  immUniform1i("colors_len", 0); /* "simple" mode */
84  immUniform1f("dash_width", 6.0f);
85  immUniform1f("dash_factor", 0.5f);
86 
88  immVertex2fv(shdr_pos, mval_src);
89  immVertex2fv(shdr_pos, mval_dst);
90  immEnd();
91 
93 }
94 
95 #define MAX_METADATA_STR 1024
96 
97 static const char *meta_data_list[] = {
98  "File",
99  "Strip",
100  "Date",
101  "RenderTime",
102  "Note",
103  "Marker",
104  "Time",
105  "Frame",
106  "Camera",
107  "Scene",
108 };
109 
110 BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset)
111 {
112  return (IMB_metadata_get_field(
113  ibuf->metadata, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) &&
114  r_str[0]);
115 }
116 
118 {
119  /* Metadata field stored by Blender for multi-layer EXR images. Is rather
120  * useless to be viewed all the time. Can still be seen in the Metadata
121  * panel. */
122  if (STREQ(field, "BlenderMultiChannel")) {
123  return false;
124  }
125  /* Is almost always has value "scanlineimage", also useless to be seen
126  * all the time. */
127  if (STREQ(field, "type")) {
128  return false;
129  }
130  return !BKE_stamp_is_known_field(field);
131 }
132 
134  int fontid;
135  int xmin, ymin;
139 
140 static void metadata_custom_draw_fields(const char *field, const char *value, void *ctx_v)
141 {
142  if (!metadata_is_custom_drawable(field)) {
143  return;
144  }
146  char temp_str[MAX_METADATA_STR];
147  BLI_snprintf(temp_str, MAX_METADATA_STR, "%s: %s", field, value);
148  BLF_position(ctx->fontid, ctx->xmin, ctx->ymin + ctx->current_y, 0.0f);
149  BLF_draw(ctx->fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
150  ctx->current_y += ctx->vertical_offset;
151 }
152 
153 static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const bool is_top)
154 {
155  char temp_str[MAX_METADATA_STR];
156  int ofs_y = 0;
157  const float height = BLF_height_max(fontid);
158  const float margin = height / 8;
159  const float vertical_offset = (height + margin);
160 
161  /* values taking margins into account */
162  const float descender = BLF_descender(fontid);
163  const float xmin = (rect->xmin + margin);
164  const float xmax = (rect->xmax - margin);
165  const float ymin = (rect->ymin + margin) - descender;
166  const float ymax = (rect->ymax - margin) - descender;
167 
168  if (is_top) {
169  for (int i = 0; i < 4; i++) {
170  /* first line */
171  if (i == 0) {
172  bool do_newline = false;
173  int len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[0]);
174  if (metadata_is_valid(ibuf, temp_str, 0, len)) {
175  BLF_position(fontid, xmin, ymax - vertical_offset, 0.0f);
176  BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
177  do_newline = true;
178  }
179 
180  len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[1]);
181  if (metadata_is_valid(ibuf, temp_str, 1, len)) {
182  int line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
183  BLF_position(fontid, xmax - line_width, ymax - vertical_offset, 0.0f);
184  BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
185  do_newline = true;
186  }
187 
188  if (do_newline) {
189  ofs_y += vertical_offset;
190  }
191  } /* Strip */
192  else if (ELEM(i, 1, 2)) {
193  int len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]);
194  if (metadata_is_valid(ibuf, temp_str, i + 1, len)) {
195  BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f);
196  BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
197  ofs_y += vertical_offset;
198  }
199  } /* Note (wrapped) */
200  else if (i == 3) {
201  int len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]);
202  if (metadata_is_valid(ibuf, temp_str, i + 1, len)) {
203  struct ResultBLF info;
204  BLF_enable(fontid, BLF_WORD_WRAP);
205  BLF_wordwrap(fontid, ibuf->x - (margin * 2));
206  BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f);
207  BLF_draw_ex(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX, &info);
208  BLF_wordwrap(fontid, 0);
209  BLF_disable(fontid, BLF_WORD_WRAP);
210  ofs_y += vertical_offset * info.lines;
211  }
212  }
213  else {
214  int len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]);
215  if (metadata_is_valid(ibuf, temp_str, i + 1, len)) {
216  int line_width = BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
217  BLF_position(fontid, xmax - line_width, ymax - vertical_offset - ofs_y, 0.0f);
218  BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
219  ofs_y += vertical_offset;
220  }
221  }
222  }
223  }
224  else {
226  ctx.fontid = fontid;
227  ctx.xmin = xmin;
228  ctx.ymin = ymin;
229  ctx.current_y = ofs_y;
230  ctx.vertical_offset = vertical_offset;
232  int ofs_x = 0;
233  ofs_y = ctx.current_y;
234  for (int i = 5; i < 10; i++) {
235  int len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i]);
236  if (metadata_is_valid(ibuf, temp_str, i, len)) {
237  BLF_position(fontid, xmin + ofs_x, ymin + ofs_y, 0.0f);
238  BLF_draw(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX);
239 
240  ofs_x += BLF_width(fontid, temp_str, BLF_DRAW_STR_DUMMY_MAX) + UI_UNIT_X;
241  }
242  }
243  }
244 }
245 
247  int count;
249 
250 static void metadata_custom_count_fields(const char *field, const char *UNUSED(value), void *ctx_v)
251 {
252  if (!metadata_is_custom_drawable(field)) {
253  return;
254  }
256  ctx->count++;
257 }
258 
259 static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top)
260 {
261  const float height = BLF_height_max(fontid);
262  const float margin = (height / 8);
263  char str[MAX_METADATA_STR] = "";
264  short count = 0;
265 
266  if (is_top) {
267  if (metadata_is_valid(ibuf, str, 0, 0) || metadata_is_valid(ibuf, str, 1, 0)) {
268  count++;
269  }
270  for (int i = 2; i < 5; i++) {
271  if (metadata_is_valid(ibuf, str, i, 0)) {
272  if (i == 4) {
273  struct {
274  struct ResultBLF info;
275  rctf rect;
276  } wrap;
277 
278  BLF_enable(fontid, BLF_WORD_WRAP);
279  BLF_wordwrap(fontid, ibuf->x - (margin * 2));
280  BLF_boundbox_ex(fontid, str, sizeof(str), &wrap.rect, &wrap.info);
281  BLF_wordwrap(fontid, 0);
282  BLF_disable(fontid, BLF_WORD_WRAP);
283 
284  count += wrap.info.lines;
285  }
286  else {
287  count++;
288  }
289  }
290  }
291  }
292  else {
293  for (int i = 5; i < 10; i++) {
294  if (metadata_is_valid(ibuf, str, i, 0)) {
295  count = 1;
296  break;
297  }
298  }
300  ctx.count = 0;
302  count += ctx.count;
303  }
304 
305  if (count) {
306  return (height + margin) * count;
307  }
308 
309  return 0;
310 }
311 
312 /* Should be kept in sync with BKE_image_stamp_buf */
314  int x, int y, ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
315 {
316  const uiStyle *style = UI_style_get_dpi();
317 
318  if (!ibuf->metadata) {
319  return;
320  }
321 
322  /* find window pixel coordinates of origin */
323  GPU_matrix_push();
324 
325  /* offset and zoom using ogl */
327  GPU_matrix_scale_2f(zoomx, zoomy);
328 
329  BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
330 
331  /* *** upper box*** */
332 
333  /* get needed box height */
334  float box_y = metadata_box_height_get(ibuf, blf_mono_font, true);
335 
336  if (box_y) {
337  /* set up rect */
338  rctf rect;
339  BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y);
340  /* draw top box */
345  immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
347 
348  BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
350 
352  metadata_draw_imbuf(ibuf, &rect, blf_mono_font, true);
353 
355  }
356 
357  /* *** lower box*** */
358 
359  box_y = metadata_box_height_get(ibuf, blf_mono_font, false);
360 
361  if (box_y) {
362  /* set up box rect */
363  rctf rect;
364  BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin);
365  /* draw top box */
370  immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
372 
373  BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
375 
377  metadata_draw_imbuf(ibuf, &rect, blf_mono_font, false);
378 
380  }
381 
382  GPU_matrix_pop();
383 }
384 
385 #undef MAX_METADATA_STR
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
bool BKE_stamp_is_known_field(const char *field_name)
Definition: image.c:2674
#define BLF_CLIPPING
Definition: BLF_api.h:270
float BLF_width(int fontid, const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:723
void BLF_draw(int fontid, const char *str, size_t len) ATTR_NONNULL(2)
Definition: blf.c:542
#define BLF_DRAW_STR_DUMMY_MAX
Definition: BLF_api.h:283
void BLF_disable(int fontid, int option)
Definition: blf.c:283
float BLF_descender(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:779
int blf_mono_font
Definition: blf.c:70
void BLF_draw_ex(int fontid, const char *str, size_t len, struct ResultBLF *r_info) ATTR_NONNULL(2)
Definition: blf.c:525
void BLF_boundbox_ex(int fontid, const char *str, size_t len, struct rctf *box, struct ResultBLF *r_info) ATTR_NONNULL(2)
Definition: blf.c:676
void BLF_size(int fontid, int size, int dpi)
Definition: blf.c:367
void BLF_enable(int fontid, int option)
Definition: blf.c:274
int BLF_height_max(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:757
#define BLF_WORD_WRAP
Definition: BLF_api.h:275
void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax)
Definition: blf.c:810
void BLF_wordwrap(int fontid, int wrap_width)
Definition: blf.c:822
void BLF_position(int fontid, float x, float y, float z)
Definition: blf.c:312
#define BLI_INLINE
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition: rct.c:436
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
void immUniform2f(const char *name, float x, float y)
void immUnbindProgram(void)
void immUniformThemeColor(int color_id)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
void immUniform1i(const char *name, int x)
void immUniformThemeColor3(int color_id)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:142
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:232
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
void GPU_matrix_translate_2f(float x, float y)
Definition: gpu_matrix.cc:190
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:365
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
void GPU_line_width(float width)
Definition: gpu_state.cc:173
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:279
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Contains defines and structs used throughout the imbuf module.
void IMB_metadata_foreach(struct ImBuf *ibuf, IMBMetadataForeachCb callback, void *userdata)
Definition: metadata.c:107
bool IMB_metadata_get_field(struct IDProperty *metadata, const char *key, char *value, const size_t len)
Definition: metadata.c:60
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
const struct uiStyle * UI_style_get_dpi(void)
#define UI_DPI_FAC
Definition: UI_interface.h:309
#define UI_UNIT_X
@ TH_METADATA_TEXT
Definition: UI_resources.h:348
@ TH_VIEW_OVERLAY
Definition: UI_resources.h:343
@ TH_METADATA_BG
Definition: UI_resources.h:347
void UI_FontThemeColor(int fontid, int colorid)
Definition: resources.c:1156
unsigned int U
Definition: btGjkEpa3.h:78
void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
Definition: ed_draw.c:313
#define MAX_METADATA_STR
Definition: ed_draw.c:95
struct MetadataCustomCountContext MetadataCustomCountContext
static void metadata_custom_count_fields(const char *field, const char *UNUSED(value), void *ctx_v)
Definition: ed_draw.c:250
static void metadata_custom_draw_fields(const char *field, const char *value, void *ctx_v)
Definition: ed_draw.c:140
static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top)
Definition: ed_draw.c:259
static const char * meta_data_list[]
Definition: ed_draw.c:97
BLI_INLINE bool metadata_is_custom_drawable(const char *field)
Definition: ed_draw.c:117
struct MetadataCustomDrawContext MetadataCustomDrawContext
static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const bool is_top)
Definition: ed_draw.c:153
BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset)
Definition: ed_draw.c:110
void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *region, void *arg_info)
Definition: ed_draw.c:62
#define str(s)
uint pos
int count
format
Definition: logImageCore.h:47
static GPUContext * wrap(Context *ctx)
struct IDProperty * metadata
int lines
Definition: BLF_api.h:296
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
uiFontStyle widgetlabel
int y
Definition: WM_types.h:581
int x
Definition: WM_types.h:581
struct wmEvent * eventstate
uint len