Blender  V2.93
icons_rasterize.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 
20 #include "MEM_guardedalloc.h"
21 
22 #include "BLI_bitmap_draw_2d.h"
23 #include "BLI_math_geom.h"
24 #include "BLI_utildefines.h"
25 
26 #include "IMB_imbuf.h"
27 #include "IMB_imbuf_types.h"
28 
29 #include "BKE_icons.h"
30 
31 #include "BLI_strict_flags.h"
32 
34  int pt[3][2];
35  const uint *color;
36  /* only for smooth shading */
37  struct {
38  float pt_fl[3][2];
39  uint color_u[3][4];
40  } smooth;
41  int rect_size[2];
43 };
44 
45 static void tri_fill_flat(int x, int x_end, int y, void *user_data)
46 {
47  struct UserRasterInfo *data = user_data;
48  uint *p = &data->rect[(y * data->rect_size[1]) + x];
49  uint col = data->color[0];
50  while (x++ != x_end) {
51  *p++ = col;
52  }
53 }
54 
55 static void tri_fill_smooth(int x, int x_end, int y, void *user_data)
56 {
57  struct UserRasterInfo *data = user_data;
58  uint *p = &data->rect[(y * data->rect_size[1]) + x];
59  float pt_step_fl[2] = {(float)x, (float)y};
60  while (x++ != x_end) {
61  float w[3];
62  barycentric_weights_v2_clamped(UNPACK3(data->smooth.pt_fl), pt_step_fl, w);
63 
64  uint col_u[4] = {0, 0, 0, 0};
65  for (uint corner = 0; corner < 3; corner++) {
66  for (uint chan = 0; chan < 4; chan++) {
67  col_u[chan] += data->smooth.color_u[corner][chan] * (uint)(w[corner] * 255.0f);
68  }
69  }
70  union {
71  uint as_u32;
72  uchar as_bytes[4];
73  } col;
74  col.as_bytes[0] = (uchar)(col_u[0] / 255);
75  col.as_bytes[1] = (uchar)(col_u[1] / 255);
76  col.as_bytes[2] = (uchar)(col_u[2] / 255);
77  col.as_bytes[3] = (uchar)(col_u[3] / 255);
78  *p++ = col.as_u32;
79 
80  pt_step_fl[0] += 1.0f;
81  }
82 }
83 
85  const unsigned int size_x,
86  const unsigned int size_y)
87 {
88  const int coords_len = geom->coords_len;
89 
90  const uchar(*pos)[2] = geom->coords;
91  const uint *col = (void *)geom->colors;
92 
93  /* TODO(campbell): Currently rasterizes to fixed size, then scales.
94  * Should rasterize to double size for eg instead. */
95  const int rect_size[2] = {max_ii(256, (int)size_x * 2), max_ii(256, (int)size_y * 2)};
96 
97  ImBuf *ibuf = IMB_allocImBuf((uint)rect_size[0], (uint)rect_size[1], 32, IB_rect);
98 
99  struct UserRasterInfo data;
100 
101  data.rect_size[0] = rect_size[0];
102  data.rect_size[1] = rect_size[1];
103 
104  data.rect = ibuf->rect;
105 
106  float scale[2];
107  const bool use_scale = (rect_size[0] != 256) || (rect_size[1] != 256);
108 
109  if (use_scale) {
110  scale[0] = ((float)rect_size[0] / 256.0f);
111  scale[1] = ((float)rect_size[1] / 256.0f);
112  }
113 
114  for (int t = 0; t < coords_len; t += 1, pos += 3, col += 3) {
115  if (use_scale) {
116  ARRAY_SET_ITEMS(data.pt[0], (int)(pos[0][0] * scale[0]), (int)(pos[0][1] * scale[1]));
117  ARRAY_SET_ITEMS(data.pt[1], (int)(pos[1][0] * scale[0]), (int)(pos[1][1] * scale[1]));
118  ARRAY_SET_ITEMS(data.pt[2], (int)(pos[2][0] * scale[0]), (int)(pos[2][1] * scale[1]));
119  }
120  else {
121  ARRAY_SET_ITEMS(data.pt[0], UNPACK2(pos[0]));
122  ARRAY_SET_ITEMS(data.pt[1], UNPACK2(pos[1]));
123  ARRAY_SET_ITEMS(data.pt[2], UNPACK2(pos[2]));
124  }
125  data.color = col;
126  if ((col[0] == col[1]) && (col[0] == col[2])) {
128  }
129  else {
130  ARRAY_SET_ITEMS(data.smooth.pt_fl[0], UNPACK2_EX((float), data.pt[0], ));
131  ARRAY_SET_ITEMS(data.smooth.pt_fl[1], UNPACK2_EX((float), data.pt[1], ));
132  ARRAY_SET_ITEMS(data.smooth.pt_fl[2], UNPACK2_EX((float), data.pt[2], ));
133  ARRAY_SET_ITEMS(data.smooth.color_u[0], UNPACK4_EX((uint), ((uchar *)(col + 0)), ));
134  ARRAY_SET_ITEMS(data.smooth.color_u[1], UNPACK4_EX((uint), ((uchar *)(col + 1)), ));
135  ARRAY_SET_ITEMS(data.smooth.color_u[2], UNPACK4_EX((uint), ((uchar *)(col + 2)), ));
137  }
138  }
139  IMB_scaleImBuf(ibuf, size_x, size_y);
140  return ibuf;
141 }
142 
144 {
145  const int length = 3 * geom->coords_len;
146 
147  for (int i = 0; i < length; i++) {
148  float rgb[3], hsl[3];
149 
150  rgb_uchar_to_float(rgb, geom->colors[i]);
151  rgb_to_hsl_v(rgb, hsl);
152  hsl_to_rgb(hsl[0], hsl[1], 1.0f - hsl[2], &rgb[0], &rgb[1], &rgb[2]);
153  rgb_float_to_uchar(geom->colors[i], rgb);
154  }
155 }
typedef float(TangentPoint)[2]
void BLI_bitmap_draw_2d_tri_v2i(const int p1[2], const int p2[2], const int p3[2], void(*callback)(int x, int x_end, int y, void *), void *user_data)
MINLINE int max_ii(int a, int b)
void hsl_to_rgb(float h, float s, float l, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:48
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
Definition: math_color.c:315
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
Definition: math_color.c:407
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
Definition: math_color.c:422
void barycentric_weights_v2_clamped(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
Definition: math_geom.c:3971
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK2(a)
#define ARRAY_SET_ITEMS(...)
#define UNPACK2_EX(pre, a, post)
#define UNPACK4_EX(pre, a, post)
#define UNPACK3(a)
_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
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
Definition: scaling.c:1667
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:478
Contains defines and structs used throughout the imbuf module.
@ IB_rect
Read Guarded memory(de)allocation.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
void * user_data
uint pos
uint col
static void tri_fill_flat(int x, int x_end, int y, void *user_data)
ImBuf * BKE_icon_geom_rasterize(const struct Icon_Geom *geom, const unsigned int size_x, const unsigned int size_y)
static void tri_fill_smooth(int x, int x_end, int y, void *user_data)
void BKE_icon_geom_invert_lightness(struct Icon_Geom *geom)
int coords_len
Definition: BKE_icons.h:78
unsigned char(* colors)[4]
Definition: BKE_icons.h:81
unsigned char(* coords)[2]
Definition: BKE_icons.h:80
unsigned int * rect
const uint * color
float pt_fl[3][2]
uint color_u[3][4]
struct UserRasterInfo::@91 smooth
ccl_device_inline int rect_size(int4 rect)
Definition: util_rect.h:65