Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions webrender/src/platform/macos/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ use core_text;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use webrender_traits::{ColorU, FontKey, FontRenderMode, GlyphDimensions, GlyphOptions};
use gamma_lut::{GammaLut, Color as ColorLut};

pub type NativeFontHandle = CGFont;

pub struct FontContext {
cg_fonts: HashMap<FontKey, CGFont>,
ct_fonts: HashMap<(FontKey, Au), CTFont>,
gamma_lut: GammaLut,
}

pub struct RasterizedGlyph {
Expand Down Expand Up @@ -92,9 +94,14 @@ impl FontContext {
pub fn new() -> FontContext {
debug!("Test for subpixel AA support: {}", supports_subpixel_aa());

// Force CG to use sRGB color space to gamma correct.
let contrast = 0.0;
let gamma = 0.0;

FontContext {
cg_fonts: HashMap::new(),
ct_fonts: HashMap::new(),
gamma_lut: GammaLut::new(contrast, gamma, gamma),
}
}

Expand Down Expand Up @@ -158,9 +165,31 @@ impl FontContext {
})
}

// Assumes the pixels here are linear values from CG
fn gamma_correct_pixels(&self, pixels: &mut Vec<u8>, width: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: As far as I understand it, pixels's length cannot change, right? If so, you could probably make it a &mut [u8] so you save an indirection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh good point. Thanks! Since I already have the dwrite gamma correction also using vector, can I fix this + dwrite + the gamma-lut library in a follow up patch? Too many patches in mid flight right now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds fine to me :)

height: usize, render_mode: FontRenderMode,
color: ColorU) {
// Then convert back to gamma corrected values.
let color_lut = ColorLut::new(color.r,
color.g,
color.b,
color.a);
match render_mode {
FontRenderMode::Alpha => {
self.gamma_lut.preblend_grayscale_bgra(pixels, width,
height, color_lut);
},
FontRenderMode::Subpixel => {
self.gamma_lut.preblend_bgra(pixels, width, height, color_lut);
},
_ => {} // Again, give mono untouched since only the alpha matters.
}
}

#[allow(dead_code)]
fn print_glyph_data(&mut self, data: &Vec<u8>, width: usize, height: usize) {
// Rust doesn't have step_by support on stable :(
println!("Width is: {:?} height: {:?}", width, height);
for i in 0..height {
let current_height = i * width * 4;

Expand Down Expand Up @@ -266,6 +295,14 @@ impl FontContext {

let mut rasterized_pixels = cg_context.data().to_vec();

// Convert to linear space for subpixel AA.
// We explicitly do not do this for grayscale AA
if render_mode == FontRenderMode::Subpixel {
self.gamma_lut.coregraphics_convert_to_linear_bgra(&mut rasterized_pixels,
metrics.rasterized_width as usize,
metrics.rasterized_height as usize);
}

// We need to invert the pixels back since right now
// transparent pixels are actually opaque white.
for i in 0..metrics.rasterized_height {
Expand All @@ -288,6 +325,12 @@ impl FontContext {
} // end row
} // end height

self.gamma_correct_pixels(&mut rasterized_pixels,
metrics.rasterized_width as usize,
metrics.rasterized_height as usize,
render_mode,
color);

Some(RasterizedGlyph {
width: metrics.rasterized_width,
height: metrics.rasterized_height,
Expand Down