From 48e5128fe87c9593f0a0cd9938e1f3c114c271b8 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Wed, 22 May 2024 16:56:30 +0100 Subject: [PATCH] Use blend function from the image crate --- examples/simple.rs | 61 ++++------------------------------------------ 1 file changed, 5 insertions(+), 56 deletions(-) diff --git a/examples/simple.rs b/examples/simple.rs index 5265b55e..a163f5de 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -5,7 +5,7 @@ //! and and then renders it into a PNG using the `image` crate. use image::codecs::png::PngEncoder; -use image::{self, Rgba, RgbaImage}; +use image::{self, Pixel, Rgba, RgbaImage}; use parley::layout::{Alignment, GlyphRun, Layout}; use parley::style::{FontStack, FontWeight, StyleProperty}; use parley::{FontContext, LayoutContext}; @@ -16,56 +16,6 @@ use swash::scale::{Render, ScaleContext, Source, StrikeWith}; use swash::zeno; use swash::{FontRef, GlyphId}; -fn u8_to_float(num: u8) -> f32 { - num as f32 / 255.0 -} - -fn float_to_u8(num: f32) -> u8 { - (num * 255.0) as u8 -} - -fn to_linear_rgb(srgb: f32) -> f32 { - if srgb <= 0.04045 { - srgb / 12.92 - } else { - ((srgb + 0.055) / 1.055).powf(2.4) - } -} - -fn to_srgb(linear_rgb: f32) -> f32 { - if linear_rgb <= 0.0031308 { - linear_rgb * 12.92 - } else { - 1.055 * linear_rgb.powf(1.0 / 2.4) - 0.055 - } -} - -fn blend_px_gamma_corrected(existing: Rgba, color: Color, alpha: u8) -> Rgba { - let [r1, g1, b1, _] = existing.0.map(|x| to_linear_rgb(u8_to_float(x))); - let [r2, g2, b2] = [color.r, color.g, color.b].map(|x| to_linear_rgb(u8_to_float(x))); - - let a = u8_to_float(alpha); - let inv_a = 1.0 - a; - - // Blend pixel with underlying color - let r = a * r2 + inv_a * r1; - let g = a * g2 + inv_a * g1; - let b = a * b2 + inv_a * b1; - - Rgba([r, g, b, 1.0].map(|x| float_to_u8(to_srgb(x)))) -} - -fn blend_px_naive(existing: Rgba, color: Color, alpha: u8) -> Rgba { - let inv_a = (255 - alpha) as u32; - let [r2, g2, b2, a2] = [color.r, color.g, color.b, alpha].map(u32::from); - let [r1, g1, b1, _a1] = existing.0.map(u32::from); - let r = (a2 * r2 + inv_a * r1) >> 8; - let g = (a2 * g2 + inv_a * g1) >> 8; - let b = (a2 * b2 + inv_a * b1) >> 8; - - Rgba([r as u8, g as u8, b as u8, 255]) -} - fn main() { // The text we are going to style and lay out let text = String::from( @@ -202,8 +152,8 @@ fn render_glyph_run( let y = (glyph_origin_y + off_y) as u32; let alpha = rendered_glyph.data[i]; if alpha > 0 { - let color = blend_px_naive(*img.get_pixel(x, y), color, alpha); - img.put_pixel(x, y, color); + let color = Rgba::from([color.r, color.g, color.b, alpha]); + img.get_pixel_mut(x, y).blend(&color); } i += 1; } @@ -223,9 +173,8 @@ fn render_glyph_run( let x = (glyph_origin_x + off_x as i32) as u32; let y = (glyph_origin_y + off_y as i32) as u32; if a > 0 { - let color = - blend_px_naive(*img.get_pixel(x, y), Color::rgb8(r, g, b), a); - img.put_pixel(x, y, color); + let color = Rgba::from([r, g, b, a]); + img.get_pixel_mut(x, y).blend(&color); } } }