Skip to content

Commit 1ff633d

Browse files
committed
Add support color mode.
1 parent bbb5501 commit 1ff633d

File tree

8 files changed

+467
-117
lines changed

8 files changed

+467
-117
lines changed

crates/processing_ffi/src/color.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
11
use bevy::color::{LinearRgba, Srgba};
2+
use processing::prelude::color::{ColorMode, ColorSpace};
23

3-
/// A sRGB (?) color
4+
/// A color with 4 float components and its color space.
45
#[repr(C)]
56
#[derive(Debug, Clone, Copy)]
67
pub struct Color {
7-
pub r: f32,
8-
pub g: f32,
9-
pub b: f32,
8+
pub c1: f32,
9+
pub c2: f32,
10+
pub c3: f32,
1011
pub a: f32,
12+
pub space: u8,
1113
}
1214

13-
impl From<Color> for bevy::color::Color {
14-
fn from(color: Color) -> Self {
15-
bevy::color::Color::srgba(color.r, color.g, color.b, color.a)
15+
impl Color {
16+
pub fn resolve(self, mode: &ColorMode) -> bevy::color::Color {
17+
let c1 = mode.scale(self.c1, 0);
18+
let c2 = mode.scale(self.c2, 1);
19+
let c3 = mode.scale(self.c3, 2);
20+
let ca = mode.scale(self.a, 3);
21+
mode.space.color(c1, c2, c3, ca)
1622
}
17-
}
18-
19-
impl From<LinearRgba> for Color {
20-
fn from(lin: LinearRgba) -> Self {
21-
let srgb: Srgba = lin.into();
22-
srgb.into()
23-
}
24-
}
2523

26-
impl From<Srgba> for Color {
27-
fn from(srgb: Srgba) -> Self {
24+
pub fn from_linear(lin: LinearRgba) -> Self {
2825
Color {
29-
r: srgb.red,
30-
g: srgb.green,
31-
b: srgb.blue,
32-
a: srgb.alpha,
26+
c1: lin.red,
27+
c2: lin.green,
28+
c3: lin.blue,
29+
a: lin.alpha,
30+
space: ColorSpace::Linear as u8,
3331
}
3432
}
3533
}

crates/processing_ffi/src/lib.rs

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ pub extern "C" fn processing_background_color(graphics_id: u64, color: Color) {
173173
error::clear_error();
174174
let graphics_entity = Entity::from_bits(graphics_id);
175175
error::check(|| {
176-
graphics_record_command(graphics_entity, DrawCommand::BackgroundColor(color.into()))
176+
let mode = graphics_get_color_mode(graphics_entity)?;
177+
let color = color.resolve(&mode);
178+
graphics_record_command(graphics_entity, DrawCommand::BackgroundColor(color))
177179
});
178180
}
179181

@@ -244,17 +246,45 @@ pub extern "C" fn processing_exit(exit_code: u8) {
244246
error::check(|| exit(exit_code));
245247
}
246248

249+
/// Set the color mode for a graphics context.
250+
///
251+
/// SAFETY:
252+
/// - graphics_id is a valid ID returned from graphics_create.
253+
/// - This is called from the same thread as init.
254+
#[unsafe(no_mangle)]
255+
pub extern "C" fn processing_color_mode(
256+
graphics_id: u64,
257+
space: u8,
258+
max1: f32,
259+
max2: f32,
260+
max3: f32,
261+
max_alpha: f32,
262+
) {
263+
error::clear_error();
264+
let graphics_entity = Entity::from_bits(graphics_id);
265+
error::check(|| {
266+
let space = processing::prelude::color::ColorSpace::from_u8(space)
267+
.ok_or_else(|| processing::prelude::error::ProcessingError::InvalidArgument(
268+
format!("unknown color space: {space}"),
269+
))?;
270+
let mode = processing::prelude::color::ColorMode::new(space, max1, max2, max3, max_alpha);
271+
graphics_set_color_mode(graphics_entity, mode)
272+
});
273+
}
274+
247275
/// Set the fill color.
248276
///
249277
/// SAFETY:
250278
/// - graphics_id is a valid ID returned from graphics_create.
251279
/// - This is called from the same thread as init.
252280
#[unsafe(no_mangle)]
253-
pub extern "C" fn processing_set_fill(graphics_id: u64, r: f32, g: f32, b: f32, a: f32) {
281+
pub extern "C" fn processing_set_fill(graphics_id: u64, color: Color) {
254282
error::clear_error();
255283
let graphics_entity = Entity::from_bits(graphics_id);
256-
let color = bevy::color::Color::srgba(r, g, b, a);
257-
error::check(|| graphics_record_command(graphics_entity, DrawCommand::Fill(color)));
284+
error::check(|| {
285+
let mode = graphics_get_color_mode(graphics_entity)?;
286+
graphics_record_command(graphics_entity, DrawCommand::Fill(color.resolve(&mode)))
287+
});
258288
}
259289

260290
/// Set the stroke color.
@@ -263,11 +293,13 @@ pub extern "C" fn processing_set_fill(graphics_id: u64, r: f32, g: f32, b: f32,
263293
/// - graphics_id is a valid ID returned from graphics_create.
264294
/// - This is called from the same thread as init.
265295
#[unsafe(no_mangle)]
266-
pub extern "C" fn processing_set_stroke_color(graphics_id: u64, r: f32, g: f32, b: f32, a: f32) {
296+
pub extern "C" fn processing_set_stroke_color(graphics_id: u64, color: Color) {
267297
error::clear_error();
268298
let graphics_entity = Entity::from_bits(graphics_id);
269-
let color = bevy::color::Color::srgba(r, g, b, a);
270-
error::check(|| graphics_record_command(graphics_entity, DrawCommand::StrokeColor(color)));
299+
error::check(|| {
300+
let mode = graphics_get_color_mode(graphics_entity)?;
301+
graphics_record_command(graphics_entity, DrawCommand::StrokeColor(color.resolve(&mode)))
302+
});
271303
}
272304

273305
/// Set the stroke weight.
@@ -565,7 +597,7 @@ pub unsafe extern "C" fn processing_image_readback(
565597
unsafe {
566598
let buffer_slice = std::slice::from_raw_parts_mut(buffer, buffer_len);
567599
for (i, color) in colors.iter().enumerate() {
568-
buffer_slice[i] = Color::from(*color);
600+
buffer_slice[i] = Color::from_linear(*color);
569601
}
570602
}
571603

@@ -1154,9 +1186,12 @@ pub extern "C" fn processing_light_create_directional(
11541186
) -> u64 {
11551187
error::clear_error();
11561188
let graphics_entity = Entity::from_bits(graphics_id);
1157-
error::check(|| light_create_directional(graphics_entity, color.into(), illuminance))
1158-
.map(|e| e.to_bits())
1159-
.unwrap_or(0)
1189+
error::check(|| {
1190+
let mode = graphics_get_color_mode(graphics_entity)?;
1191+
light_create_directional(graphics_entity, color.resolve(&mode), illuminance)
1192+
})
1193+
.map(|e| e.to_bits())
1194+
.unwrap_or(0)
11601195
}
11611196

11621197
#[unsafe(no_mangle)]
@@ -1169,9 +1204,12 @@ pub extern "C" fn processing_light_create_point(
11691204
) -> u64 {
11701205
error::clear_error();
11711206
let graphics_entity = Entity::from_bits(graphics_id);
1172-
error::check(|| light_create_point(graphics_entity, color.into(), intensity, range, radius))
1173-
.map(|e| e.to_bits())
1174-
.unwrap_or(0)
1207+
error::check(|| {
1208+
let mode = graphics_get_color_mode(graphics_entity)?;
1209+
light_create_point(graphics_entity, color.resolve(&mode), intensity, range, radius)
1210+
})
1211+
.map(|e| e.to_bits())
1212+
.unwrap_or(0)
11751213
}
11761214

11771215
#[unsafe(no_mangle)]
@@ -1187,9 +1225,10 @@ pub extern "C" fn processing_light_create_spot(
11871225
error::clear_error();
11881226
let graphics_entity = Entity::from_bits(graphics_id);
11891227
error::check(|| {
1228+
let mode = graphics_get_color_mode(graphics_entity)?;
11901229
light_create_spot(
11911230
graphics_entity,
1192-
color.into(),
1231+
color.resolve(&mode),
11931232
intensity,
11941233
range,
11951234
radius,

0 commit comments

Comments
 (0)