Blender V4.3
icons_rasterize.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "BLI_math_color.h"
11#include "BLI_math_geom.h"
12#include "BLI_utildefines.h"
13
14#include "IMB_imbuf.hh"
15#include "IMB_imbuf_types.hh"
16
17#include "BKE_icons.h"
18
19#include "BLI_strict_flags.h" /* Keep last. */
20
22 int pt[3][2];
23 const uint *color;
24 /* only for smooth shading */
25 struct {
26 float pt_fl[3][2];
29 int rect_size[2];
31};
32
33static void tri_fill_flat(int x, int x_end, int y, void *user_data)
34{
35 UserRasterInfo *data = static_cast<UserRasterInfo *>(user_data);
36 uint *p = &data->rect[(y * data->rect_size[1]) + x];
37 uint col = data->color[0];
38 while (x++ != x_end) {
39 *p++ = col;
40 }
41}
42
43static void tri_fill_smooth(int x, int x_end, int y, void *user_data)
44{
45 UserRasterInfo *data = static_cast<UserRasterInfo *>(user_data);
46 uint *p = &data->rect[(y * data->rect_size[1]) + x];
47 float pt_step_fl[2] = {float(x), float(y)};
48 while (x++ != x_end) {
49 float w[3];
50 barycentric_weights_v2_clamped(UNPACK3(data->smooth.pt_fl), pt_step_fl, w);
51
52 uint col_u[4] = {0, 0, 0, 0};
53 for (uint corner = 0; corner < 3; corner++) {
54 for (uint chan = 0; chan < 4; chan++) {
55 col_u[chan] += data->smooth.color_u[corner][chan] * uint(w[corner] * 255.0f);
56 }
57 }
58 union {
59 uint as_u32;
60 uchar as_bytes[4];
61 } col;
62 col.as_bytes[0] = uchar(col_u[0] / 255);
63 col.as_bytes[1] = uchar(col_u[1] / 255);
64 col.as_bytes[2] = uchar(col_u[2] / 255);
65 col.as_bytes[3] = uchar(col_u[3] / 255);
66 *p++ = col.as_u32;
67
68 pt_step_fl[0] += 1.0f;
69 }
70}
71
72ImBuf *BKE_icon_geom_rasterize(const Icon_Geom *geom, const uint size_x, const uint size_y)
73{
74 const int coords_len = geom->coords_len;
75
76 const uchar(*pos)[2] = geom->coords;
77 const uint *col = static_cast<const uint *>((void *)geom->colors);
78
79 /* TODO(@ideasman42): Currently rasterizes to fixed size, then scales.
80 * Should rasterize to double size for eg instead. */
81 const int rect_size[2] = {max_ii(256, int(size_x) * 2), max_ii(256, int(size_y) * 2)};
82
84
86
87 data.rect_size[0] = rect_size[0];
88 data.rect_size[1] = rect_size[1];
89
90 data.rect = (uint *)ibuf->byte_buffer.data;
91
92 float scale[2];
93 const bool use_scale = (rect_size[0] != 256) || (rect_size[1] != 256);
94
95 if (use_scale) {
96 scale[0] = float(rect_size[0]) / 256.0f;
97 scale[1] = float(rect_size[1]) / 256.0f;
98 }
99
100 for (int t = 0; t < coords_len; t += 1, pos += 3, col += 3) {
101 if (use_scale) {
102 ARRAY_SET_ITEMS(data.pt[0], int(pos[0][0] * scale[0]), int(pos[0][1] * scale[1]));
103 ARRAY_SET_ITEMS(data.pt[1], int(pos[1][0] * scale[0]), int(pos[1][1] * scale[1]));
104 ARRAY_SET_ITEMS(data.pt[2], int(pos[2][0] * scale[0]), int(pos[2][1] * scale[1]));
105 }
106 else {
107 ARRAY_SET_ITEMS(data.pt[0], UNPACK2(pos[0]));
108 ARRAY_SET_ITEMS(data.pt[1], UNPACK2(pos[1]));
109 ARRAY_SET_ITEMS(data.pt[2], UNPACK2(pos[2]));
110 }
111 data.color = col;
112 if ((col[0] == col[1]) && (col[0] == col[2])) {
114 }
115 else {
116 ARRAY_SET_ITEMS(data.smooth.pt_fl[0], UNPACK2_EX((float), data.pt[0], ));
117 ARRAY_SET_ITEMS(data.smooth.pt_fl[1], UNPACK2_EX((float), data.pt[1], ));
118 ARRAY_SET_ITEMS(data.smooth.pt_fl[2], UNPACK2_EX((float), data.pt[2], ));
119 ARRAY_SET_ITEMS(data.smooth.color_u[0], UNPACK4_EX((uint), ((uchar *)(col + 0)), ));
120 ARRAY_SET_ITEMS(data.smooth.color_u[1], UNPACK4_EX((uint), ((uchar *)(col + 1)), ));
121 ARRAY_SET_ITEMS(data.smooth.color_u[2], UNPACK4_EX((uint), ((uchar *)(col + 2)), ));
123 }
124 }
125 IMB_scale(ibuf, size_x, size_y, IMBScaleFilter::Box, false);
126 return ibuf;
127}
128
130{
131 const int length = 3 * geom->coords_len;
132
133 for (int i = 0; i < length; i++) {
134 float rgb[3], hsl[3];
135
136 rgb_uchar_to_float(rgb, geom->colors[i]);
137 rgb_to_hsl_v(rgb, hsl);
138 hsl_to_rgb(hsl[0], hsl[1], 1.0f - hsl[2], &rgb[0], &rgb[1], &rgb[2]);
139 rgb_float_to_uchar(geom->colors[i], rgb);
140 }
141}
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.cc:38
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
void barycentric_weights_v2_clamped(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
unsigned char uchar
unsigned int uint
#define UNPACK2(a)
#define ARRAY_SET_ITEMS(...)
#define UNPACK2_EX(pre, a, post)
#define UNPACK4_EX(pre, a, post)
#define UNPACK3(a)
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
Definition scaling.cc:779
Contains defines and structs used throughout the imbuf module.
@ IB_rect
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
draw_view in_light_buf[] float
uint col
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
static void tri_fill_flat(int x, int x_end, int y, void *user_data)
static void tri_fill_smooth(int x, int x_end, int y, void *user_data)
ImBuf * BKE_icon_geom_rasterize(const Icon_Geom *geom, const uint size_x, const uint size_y)
void BKE_icon_geom_invert_lightness(Icon_Geom *geom)
ccl_device_inline int rect_size(int4 rect)
Definition rect.h:56
int coords_len
Definition BKE_icons.h:67
unsigned char(* colors)[4]
Definition BKE_icons.h:70
unsigned char(* coords)[2]
Definition BKE_icons.h:69
ImBufByteBuffer byte_buffer
const uint * color
float pt_fl[3][2]
struct UserRasterInfo::@84 smooth