Switch to sRGBA everywhere
This commit is contained in:
parent
859fdb4bfe
commit
1e73c01845
6 changed files with 52 additions and 44 deletions
|
|
@ -1,21 +1,21 @@
|
||||||
use palette::Srgb;
|
use palette::Srgba;
|
||||||
|
|
||||||
pub fn from_image_rgb(color: image::Rgb<u8>) -> Srgb {
|
pub fn from_image_color(color: image::Rgba<u8>) -> Srgba {
|
||||||
let [r, g, b] = color.0;
|
let [r, g, b, a] = color.0;
|
||||||
Srgb::new(r, g, b).into_format()
|
Srgba::new(r, g, b, a).into_format()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_image_rgb(color: Srgb) -> image::Rgb<u8> {
|
pub fn to_image_color(color: Srgba) -> image::Rgba<u8> {
|
||||||
let color = color.into_format::<u8>();
|
let color = color.into_format::<u8, u8>();
|
||||||
image::Rgb([color.red, color.green, color.blue])
|
image::Rgba([color.red, color.green, color.blue, color.alpha])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_text_color(color: cosmic_text::Color) -> Srgb {
|
pub fn from_text_color(color: cosmic_text::Color) -> Srgba {
|
||||||
let [r, g, b, _] = color.as_rgba();
|
let [r, g, b, a] = color.as_rgba();
|
||||||
Srgb::new(r, g, b).into_format()
|
Srgba::new(r, g, b, a).into_format()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_text_color(color: Srgb) -> cosmic_text::Color {
|
pub fn to_text_color(color: Srgba) -> cosmic_text::Color {
|
||||||
let color = color.into_format::<u8>();
|
let color = color.into_format::<u8, u8>();
|
||||||
cosmic_text::Color::rgb(color.red, color.green, color.blue)
|
cosmic_text::Color::rgba(color.red, color.green, color.blue, color.alpha)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use image::RgbImage;
|
use image::RgbaImage;
|
||||||
use palette::Srgb;
|
use palette::Srgba;
|
||||||
use taffy::{AvailableSpace, NodeId, Point, Size, TaffyResult, TaffyTree};
|
use taffy::{AvailableSpace, NodeId, Point, Size, TaffyResult, TaffyTree};
|
||||||
|
|
||||||
use crate::{color, BoxedWidget, Rect, Vec2, View};
|
use crate::{color, BoxedWidget, Rect, Vec2, View};
|
||||||
|
|
@ -14,11 +14,11 @@ fn size_to_vec2(size: Size<f32>) -> Vec2 {
|
||||||
|
|
||||||
pub struct Tree<C> {
|
pub struct Tree<C> {
|
||||||
tree: TaffyTree<BoxedWidget<C>>,
|
tree: TaffyTree<BoxedWidget<C>>,
|
||||||
background: Srgb,
|
background: Srgba,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> Tree<C> {
|
impl<C> Tree<C> {
|
||||||
pub fn new(background: Srgb) -> Self {
|
pub fn new(background: Srgba) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tree: TaffyTree::new(),
|
tree: TaffyTree::new(),
|
||||||
background,
|
background,
|
||||||
|
|
@ -88,7 +88,7 @@ impl<C> Tree<C> {
|
||||||
ctx: &mut C,
|
ctx: &mut C,
|
||||||
root: NodeId,
|
root: NodeId,
|
||||||
available: Size<AvailableSpace>,
|
available: Size<AvailableSpace>,
|
||||||
) -> anyhow::Result<RgbImage> {
|
) -> anyhow::Result<RgbaImage> {
|
||||||
self.layout(ctx, root, available)?;
|
self.layout(ctx, root, available)?;
|
||||||
|
|
||||||
let layout = self.tree.layout(root)?;
|
let layout = self.tree.layout(root)?;
|
||||||
|
|
@ -97,7 +97,8 @@ impl<C> Tree<C> {
|
||||||
// TODO Check how taffy treats the border?
|
// TODO Check how taffy treats the border?
|
||||||
|
|
||||||
let (width, height) = size_to_vec2(layout.size).to_u32();
|
let (width, height) = size_to_vec2(layout.size).to_u32();
|
||||||
let mut image = RgbImage::from_pixel(width, height, color::to_image_rgb(self.background));
|
let mut image =
|
||||||
|
RgbaImage::from_pixel(width, height, color::to_image_color(self.background));
|
||||||
self.render_to_view(ctx, root, &mut View::new(&mut image))?;
|
self.render_to_view(ctx, root, &mut View::new(&mut image))?;
|
||||||
|
|
||||||
Ok(image)
|
Ok(image)
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
use image::RgbImage;
|
use image::RgbaImage;
|
||||||
use palette::Srgb;
|
use palette::{blend::Compose, Srgba};
|
||||||
|
|
||||||
use crate::{color, Rect, Vec2};
|
use crate::{color, Rect, Vec2};
|
||||||
|
|
||||||
pub struct View<'a> {
|
pub struct View<'a> {
|
||||||
area: Rect,
|
area: Rect,
|
||||||
buffer: &'a mut RgbImage,
|
buffer: &'a mut RgbaImage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> View<'a> {
|
impl<'a> View<'a> {
|
||||||
pub fn new(buffer: &'a mut RgbImage) -> Self {
|
pub fn new(buffer: &'a mut RgbaImage) -> Self {
|
||||||
let size = Vec2::from_u32(buffer.width(), buffer.height());
|
let size = Vec2::from_u32(buffer.width(), buffer.height());
|
||||||
let area = Rect::from_nw(Vec2::ZERO, size);
|
let area = Rect::from_nw(Vec2::ZERO, size);
|
||||||
Self { area, buffer }
|
Self { area, buffer }
|
||||||
|
|
@ -35,22 +35,30 @@ impl<'a> View<'a> {
|
||||||
pos + self.area.corner_nw()
|
pos + self.area.corner_nw()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, pos: Vec2) -> Option<Srgb> {
|
pub fn get(&self, pos: Vec2) -> Option<Srgba> {
|
||||||
let (x, y) = self.pos_to_buffer_pos(pos).to_u32();
|
let (x, y) = self.pos_to_buffer_pos(pos).to_u32();
|
||||||
let pixel = self.buffer.get_pixel_checked(x, y)?;
|
let pixel = self.buffer.get_pixel_checked(x, y)?;
|
||||||
Some(color::from_image_rgb(*pixel))
|
Some(color::from_image_color(*pixel))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, pos: Vec2, color: Srgb) {
|
pub fn set(&mut self, pos: Vec2, color: Srgba) {
|
||||||
let (x, y) = self.pos_to_buffer_pos(pos).to_u32();
|
let (x, y) = self.pos_to_buffer_pos(pos).to_u32();
|
||||||
if let Some(pixel) = self.buffer.get_pixel_mut_checked(x, y) {
|
if let Some(pixel) = self.buffer.get_pixel_mut_checked(x, y) {
|
||||||
*pixel = color::to_image_rgb(color);
|
let below = color::from_image_color(*pixel);
|
||||||
|
*pixel = color::to_image_color(color.atop(below));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace(&mut self, pos: Vec2, color: Srgba) {
|
||||||
|
let (x, y) = self.pos_to_buffer_pos(pos).to_u32();
|
||||||
|
if let Some(pixel) = self.buffer.get_pixel_mut_checked(x, y) {
|
||||||
|
*pixel = color::to_image_color(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// More complicated drawing primitives
|
// More complicated drawing primitives
|
||||||
|
|
||||||
pub fn rect(&mut self, area: Rect, color: Srgb) {
|
pub fn rect(&mut self, area: Rect, color: Srgba) {
|
||||||
let nw = area.corner_nw();
|
let nw = area.corner_nw();
|
||||||
let se = area.corner_se();
|
let se = area.corner_se();
|
||||||
for y in nw.y..=se.y {
|
for y in nw.y..=se.y {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use cosmic_text::{Attrs, Buffer, Color, FontSystem, Metrics, Shaping, SwashCache};
|
use cosmic_text::{Attrs, Buffer, FontSystem, Metrics, Shaping, SwashCache};
|
||||||
use palette::Srgb;
|
use palette::Srgba;
|
||||||
use taffy::prelude::{AvailableSpace, Size};
|
use taffy::prelude::{AvailableSpace, Size};
|
||||||
|
|
||||||
use crate::{color, Rect, Vec2, View, Widget};
|
use crate::{color, Rect, Vec2, View, Widget};
|
||||||
|
|
@ -32,12 +32,12 @@ pub trait HasFontStuff {
|
||||||
|
|
||||||
pub struct Text {
|
pub struct Text {
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
color: Srgb,
|
color: Srgba,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Text {
|
impl Text {
|
||||||
/// Default text color.
|
/// Default text color.
|
||||||
const COLOR: Srgb = Srgb::new(0.0, 0.0, 0.0);
|
const COLOR: Srgba = Srgba::new(0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
// Default shaping strategy.
|
// Default shaping strategy.
|
||||||
const SHAPING: Shaping = Shaping::Advanced;
|
const SHAPING: Shaping = Shaping::Advanced;
|
||||||
|
|
@ -81,7 +81,7 @@ impl Text {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn color(mut self, color: Srgb) -> Self {
|
pub fn color(mut self, color: Srgba) -> Self {
|
||||||
self.color = color;
|
self.color = color;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use cosmic_text::{Attrs, Metrics};
|
use cosmic_text::{Attrs, Metrics};
|
||||||
use palette::Srgb;
|
use palette::Srgba;
|
||||||
use showbits_common::{
|
use showbits_common::{
|
||||||
color,
|
|
||||||
widgets::{FontStuff, HasFontStuff, Text},
|
widgets::{FontStuff, HasFontStuff, Text},
|
||||||
Tree, WidgetExt,
|
Tree, WidgetExt,
|
||||||
};
|
};
|
||||||
|
|
@ -67,7 +66,7 @@ impl Drawer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_test(&mut self) -> anyhow::Result<()> {
|
fn on_test(&mut self) -> anyhow::Result<()> {
|
||||||
let mut tree = Tree::<Context>::new(Srgb::new(1.0, 1.0, 1.0));
|
let mut tree = Tree::<Context>::new(Srgba::new(1.0, 1.0, 1.0, 1.0));
|
||||||
|
|
||||||
let root = Text::simple(
|
let root = Text::simple(
|
||||||
&mut self.ctx.font_stuff,
|
&mut self.ctx.font_stuff,
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ use escpos::{
|
||||||
printer::Printer as EPrinter,
|
printer::Printer as EPrinter,
|
||||||
utils::{PageCode, Protocol, GS},
|
utils::{PageCode, Protocol, GS},
|
||||||
};
|
};
|
||||||
use image::{Rgb, RgbImage};
|
use image::{Rgba, RgbaImage};
|
||||||
use showbits_common::Tree;
|
use showbits_common::{color, Tree};
|
||||||
use taffy::{AvailableSpace, NodeId, Size};
|
use taffy::{AvailableSpace, NodeId, Size};
|
||||||
|
|
||||||
pub struct Printer {
|
pub struct Printer {
|
||||||
|
|
@ -91,7 +91,7 @@ impl Printer {
|
||||||
/// https://download4.epson.biz/sec_pubs/pos/reference_en/escpos/gs_lv_0.html
|
/// https://download4.epson.biz/sec_pubs/pos/reference_en/escpos/gs_lv_0.html
|
||||||
fn print_image_to_printer(
|
fn print_image_to_printer(
|
||||||
printer: &mut EPrinter<FileDriver>,
|
printer: &mut EPrinter<FileDriver>,
|
||||||
image: &RgbImage,
|
image: &RgbaImage,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
assert_eq!(Self::WIDTH % 8, 0);
|
assert_eq!(Self::WIDTH % 8, 0);
|
||||||
assert_eq!(image.width(), Self::WIDTH);
|
assert_eq!(image.width(), Self::WIDTH);
|
||||||
|
|
@ -122,7 +122,7 @@ impl Printer {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_horizontal_byte_starting_at(image: &RgbImage, x: u32, y: u32) -> u8 {
|
fn get_horizontal_byte_starting_at(image: &RgbaImage, x: u32, y: u32) -> u8 {
|
||||||
let p7 = Self::pixel_to_bit(*image.get_pixel(x, y));
|
let p7 = Self::pixel_to_bit(*image.get_pixel(x, y));
|
||||||
let p6 = Self::pixel_to_bit(*image.get_pixel(x + 1, y));
|
let p6 = Self::pixel_to_bit(*image.get_pixel(x + 1, y));
|
||||||
let p5 = Self::pixel_to_bit(*image.get_pixel(x + 2, y));
|
let p5 = Self::pixel_to_bit(*image.get_pixel(x + 2, y));
|
||||||
|
|
@ -148,9 +148,9 @@ impl Printer {
|
||||||
///
|
///
|
||||||
/// Instead of doing the physically accurate thing, I do what makes the most
|
/// Instead of doing the physically accurate thing, I do what makes the most
|
||||||
/// sense visually.
|
/// sense visually.
|
||||||
fn pixel_to_bit(pixel: Rgb<u8>) -> bool {
|
fn pixel_to_bit(pixel: Rgba<u8>) -> bool {
|
||||||
let [r, g, b] = pixel.0;
|
let color = color::from_image_color(pixel);
|
||||||
let sum = (r as u32) + (g as u32) + (b as u32);
|
let avg = (color.red + color.green + color.blue) / 3.0;
|
||||||
sum <= 3 * 255 / 2 // true == black
|
avg < 0.5 // true == black
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue