From bfb07147cde7353e2a3a0354862df0bf674ffd5f Mon Sep 17 00:00:00 2001 From: grovesNL Date: Mon, 15 Jan 2024 21:13:50 -0330 Subject: [PATCH] Don't convert web text colors to linear --- src/lib.rs | 2 +- src/shader.wgsl | 37 ++++++++++++++++++++++++++----------- src/text_atlas.rs | 2 ++ src/text_render.rs | 21 +++++++++++++++++---- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 64373ca..b9194c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,7 +51,7 @@ pub(crate) struct GlyphToRender { dim: [u16; 2], uv: [u16; 2], color: u32, - content_type: u32, + content_type_with_srgb: [u16; 2], depth: f32, } diff --git a/src/shader.wgsl b/src/shader.wgsl index 337f788..d7f7d86 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -4,7 +4,7 @@ struct VertexInput { @location(1) dim: u32, @location(2) uv: u32, @location(3) color: u32, - @location(4) content_type: u32, + @location(4) content_type_with_srgb: u32, @location(5) depth: f32, } @@ -32,8 +32,7 @@ var mask_atlas_texture: texture_2d; @group(0) @binding(3) var atlas_sampler: sampler; -fn srgb_to_linear(srgb: u32) -> f32 { - let c = f32(srgb) / 255.0; +fn srgb_to_linear(c: f32) -> f32 { if c <= 0.04045 { return c / 12.92; } else { @@ -78,15 +77,31 @@ fn vs_main(in_vert: VertexInput) -> VertexOutput { vert_output.position.y *= -1.0; - vert_output.color = vec4( - srgb_to_linear((color & 0x00ff0000u) >> 16u), - srgb_to_linear((color & 0x0000ff00u) >> 8u), - srgb_to_linear(color & 0x000000ffu), - f32((color & 0xff000000u) >> 24u) / 255.0, - ); + let content_type = in_vert.content_type_with_srgb & 0xffffu; + let srgb = (in_vert.content_type_with_srgb & 0xffff0000u) >> 16u; + + switch srgb { + case 0u: { + vert_output.color = vec4( + f32((color & 0x00ff0000u) >> 16u) / 255.0, + f32((color & 0x0000ff00u) >> 8u) / 255.0, + f32(color & 0x000000ffu) / 255.0, + f32((color & 0xff000000u) >> 24u) / 255.0, + ); + } + case 1u: { + vert_output.color = vec4( + srgb_to_linear(f32((color & 0x00ff0000u) >> 16u) / 255.0), + srgb_to_linear(f32((color & 0x0000ff00u) >> 8u) / 255.0), + srgb_to_linear(f32(color & 0x000000ffu) / 255.0), + f32((color & 0xff000000u) >> 24u) / 255.0, + ); + } + default: {} + } var dim: vec2 = vec2(0u); - switch in_vert.content_type { + switch content_type { case 0u: { dim = textureDimensions(color_atlas_texture); break; @@ -98,7 +113,7 @@ fn vs_main(in_vert: VertexInput) -> VertexOutput { default: {} } - vert_output.content_type = in_vert.content_type; + vert_output.content_type = content_type; vert_output.uv = vec2(uv) / vec2(dim); diff --git a/src/text_atlas.rs b/src/text_atlas.rs index 320697d..4110554 100644 --- a/src/text_atlas.rs +++ b/src/text_atlas.rs @@ -271,6 +271,7 @@ pub struct TextAtlas { pub(crate) shader: ShaderModule, pub(crate) vertex_buffers: [wgpu::VertexBufferLayout<'static>; 1], pub(crate) format: TextureFormat, + pub(crate) color_mode: ColorMode, } impl TextAtlas { @@ -450,6 +451,7 @@ impl TextAtlas { shader, vertex_buffers, format, + color_mode, } } diff --git a/src/text_render.rs b/src/text_render.rs index a1395d3..9818bd1 100644 --- a/src/text_render.rs +++ b/src/text_render.rs @@ -1,6 +1,6 @@ use crate::{ - FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError, RenderError, - Resolution, SwashCache, SwashContent, TextArea, TextAtlas, + ColorMode, FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError, + RenderError, Resolution, SwashCache, SwashContent, TextArea, TextAtlas, }; use std::{iter, mem::size_of, slice, sync::Arc}; use wgpu::{ @@ -276,7 +276,13 @@ impl TextRenderer { dim: [width as u16, height as u16], uv: [atlas_x, atlas_y], color: color.0, - content_type: content_type as u32, + content_type_with_srgb: [ + content_type as u16, + match atlas.color_mode { + ColorMode::Accurate => TextColorConversion::ConvertToLinear, + ColorMode::Web => TextColorConversion::None, + } as u16, + ], depth, }) .take(4), @@ -405,13 +411,20 @@ impl TextRenderer { } } -#[repr(u32)] +#[repr(u16)] #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum ContentType { Color = 0, Mask = 1, } +#[repr(u16)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +enum TextColorConversion { + None = 0, + ConvertToLinear = 1, +} + fn next_copy_buffer_size(size: u64) -> u64 { let align_mask = COPY_BUFFER_ALIGNMENT - 1; ((size.next_power_of_two() + align_mask) & !align_mask).max(COPY_BUFFER_ALIGNMENT)