Support color emoji

This commit is contained in:
Jeremy Soller 2022-10-07 12:42:23 -06:00
parent 1651c4f792
commit deb993d9c3
No known key found for this signature in database
GPG key ID: 87F211AF2BE4C2FE
3 changed files with 52 additions and 14 deletions

View file

@ -22,7 +22,7 @@ pub struct FontLayoutLine<'a> {
}
impl<'a> FontLayoutLine<'a> {
pub fn draw<F: FnMut(i32, i32, u8)>(&self, mut f: F) {
pub fn draw<F: FnMut(i32, i32, u32)>(&self, base: u32, mut f: F) {
for glyph in self.glyphs.iter() {
#[cfg(feature = "ab_glyph")]
if let Some(ref outline) = glyph.inner {
@ -30,7 +30,11 @@ impl<'a> FontLayoutLine<'a> {
let x = bb.min.x as i32;
let y = bb.min.y as i32;
outline.draw(|off_x, off_y, v| {
f(x + off_x as i32, y + off_y as i32, (v * 255.0) as u8);
//TODO: ensure v * 255.0 does not overflow!
let color =
((v * 255.0) as u32) << 24 |
base & 0xFFFFFF;
f(x + off_x as i32, y + off_y as i32, color);
});
}
@ -39,22 +43,51 @@ impl<'a> FontLayoutLine<'a> {
let x = bb.min.x;
let y = bb.min.y;
glyph.inner.draw(|off_x, off_y, v| {
f(x + off_x as i32, y + off_y as i32, (v * 255.0) as u8);
//TODO: ensure v * 255.0 does not overflow!
let color =
((v * 255.0) as u32) << 24 |
base & 0xFFFFFF;
f(x + off_x as i32, y + off_y as i32, color);
});
}
#[cfg(feature = "swash")]
if let Some(ref image) = glyph.inner.2 {
assert_eq!(image.content, swash::scale::image::Content::Mask);
use swash::scale::image::Content;
let x = glyph.inner.0 + image.placement.left;
let y = glyph.inner.1 - image.placement.top;
let mut i = 0;
for off_y in 0..image.placement.height as i32 {
for off_x in 0..image.placement.width as i32 {
f(x + off_x, y + off_y, image.data[i]);
i += 1;
match image.content {
Content::Mask => {
let mut i = 0;
for off_y in 0..image.placement.height as i32 {
for off_x in 0..image.placement.width as i32 {
let color =
(image.data[i] as u32) << 24 |
base & 0xFFFFFF;
f(x + off_x, y + off_y, color);
i += 1;
}
}
},
Content::Color => {
let mut i = 0;
for off_y in 0..image.placement.height as i32 {
for off_x in 0..image.placement.width as i32 {
println!("{}, {}, {:x?}", off_x, off_y, &image.data[i..i + 4]);
let color =
(image.data[i + 3] as u32) << 24 |
(image.data[i] as u32) << 16 |
(image.data[i + 1] as u32) << 8 |
(image.data[i + 2] as u32);
f(x + off_x, y + off_y, color);
i += 4;
}
}
},
Content::SubpixelMask => {
println!("TODO: SubpixelMask");
}
}
}

View file

@ -74,7 +74,14 @@ impl<'a> FontShapeGlyph<'a> {
let offset = Vector::new((x + x_offset).fract(), (y - y_offset).fract());
// Select our source order
let image_opt = Render::new(&[Source::Outline])
let image_opt = Render::new(&[
// Color outline with the first palette
Source::ColorOutline(0),
// Color bitmap with best fit selection mode
Source::ColorBitmap(StrikeWith::BestFit),
// Standard scalable outline
Source::Outline,
])
// Select a subpixel format
.format(Format::Alpha)
// Apply the fractional offset

View file

@ -203,10 +203,8 @@ fn main() {
}
}
line.draw(|x, y, alpha| {
window.pixel(line_x + x, line_y + y, Color {
data: (alpha as u32) << 24 | (font_color.data & 0x00FF_FFFF)
});
line.draw(font_color.data, |x, y, color| {
window.pixel(line_x + x, line_y + y, Color { data: color });
});
line_y += line_height;