Skip to content

Commit

Permalink
servo: Merge #11103 - gfx: Map CSS normal font weight to Regular fo…
Browse files Browse the repository at this point in the history
…nt weight on the Mac (from pcwalton:mac-font-matching); r=metajack

This series of commits fixes #9487, and improves the look of nytimes.com among others.

r? metajack

Source-Repo: https://github.com/servo/servo
Source-Revision: 1fd9c5583455b873fca1c95b2784f969870073bd

UltraBlame original commit: 18b20a707b80ee994d2b6d01f2d39fed83b2101b
  • Loading branch information
marco-c committed Oct 1, 2019
1 parent 8d67b5a commit 99d1ef4
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 49 deletions.
23 changes: 18 additions & 5 deletions servo/components/gfx/font_cache_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use std::borrow::ToOwned;
use std::collections::HashMap;
use std::mem;
use std::sync::{Arc, Mutex};
use std::u32;
use string_cache::Atom;
use style::font_face::Source;
use style::properties::longhands::font_family::computed_value::FontFamily;
Expand Down Expand Up @@ -51,9 +52,6 @@ impl FontTemplates {






for template in &mut self.templates {
let maybe_template = template.data_for_descriptor(fctx, desc);
if maybe_template.is_some() {
Expand All @@ -63,6 +61,22 @@ impl FontTemplates {



let (mut best_template_data, mut best_distance) = (None, u32::MAX);
for template in &mut self.templates {
if let Some((template_data, distance)) =
template.data_for_approximate_descriptor(fctx, desc) {
if distance < best_distance {
best_template_data = Some(template_data);
best_distance = distance
}
}
}
if best_template_data.is_some() {
return best_template_data
}




for template in &mut self.templates {
let maybe_template = template.get();
Expand All @@ -81,8 +95,7 @@ impl FontTemplates {
}
}

let template = FontTemplate::new(identifier,
maybe_data);
let template = FontTemplate::new(identifier, maybe_data);
self.templates.push(template);
}
}
Expand Down
110 changes: 76 additions & 34 deletions servo/components/gfx/font_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use font::FontHandleMethods;
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use platform::font_template::FontTemplateData;
use std::fmt::{Debug, Error, Formatter};
use std::sync::{Arc, Weak};
use std::u32;
use string_cache::Atom;
use style::computed_values::{font_stretch, font_weight};

Expand All @@ -31,13 +33,25 @@ impl FontTemplateDescriptor {
italic: italic,
}
}






#[inline]
fn distance_from(&self, other: &FontTemplateDescriptor) -> u32 {
if self.stretch != other.stretch || self.italic != other.italic {

return 1000
}
((self.weight as i16) - (other.weight as i16)).abs() as u32
}
}

impl PartialEq for FontTemplateDescriptor {
fn eq(&self, other: &FontTemplateDescriptor) -> bool {
self.weight.is_bold() == other.weight.is_bold() &&
self.stretch == other.stretch &&
self.italic == other.italic
self.weight == other.weight && self.stretch == other.stretch && self.italic == other.italic
}
}

Expand All @@ -53,6 +67,12 @@ pub struct FontTemplate {
is_valid: bool,
}

impl Debug for FontTemplate {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
self.identifier.fmt(f)
}
}




Expand Down Expand Up @@ -88,52 +108,74 @@ impl FontTemplate {


pub fn data_for_descriptor(&mut self,
fctx: &FontContextHandle,
requested_desc: &FontTemplateDescriptor)
-> Option<Arc<FontTemplateData>> {
fctx: &FontContextHandle,
requested_desc: &FontTemplateDescriptor)
-> Option<Arc<FontTemplateData>> {





match self.descriptor {
Some(actual_desc) => {
if *requested_desc == actual_desc {
Some(actual_desc) if *requested_desc == actual_desc => Some(self.data()),
Some(_) => None,
None => {
if self.instantiate(fctx).is_err() {
return None
}

if self.descriptor
.as_ref()
.expect("Instantiation succeeded but no descriptor?") == requested_desc {
Some(self.data())
} else {
None
}
},
None if self.is_valid => {
let data = self.data();
let handle: Result<FontHandle, ()> =
FontHandleMethods::new_from_template(fctx, data.clone(), None);
match handle {
Ok(handle) => {
let actual_desc = FontTemplateDescriptor::new(handle.boldness(),
handle.stretchiness(),
handle.is_italic());
let desc_match = actual_desc == *requested_desc;

self.descriptor = Some(actual_desc);
self.is_valid = true;
if desc_match {
Some(data)
} else {
None
}
}
Err(()) => {
self.is_valid = false;
debug!("Unable to create a font from template {}", self.identifier);
None
}
}
}
}



pub fn data_for_approximate_descriptor(&mut self,
font_context: &FontContextHandle,
requested_descriptor: &FontTemplateDescriptor)
-> Option<(Arc<FontTemplateData>, u32)> {
match self.descriptor {
Some(actual_descriptor) => {
Some((self.data(), actual_descriptor.distance_from(requested_descriptor)))
}
None => {
if self.instantiate(font_context).is_ok() {
let distance = self.descriptor
.as_ref()
.expect("Instantiation successful but no descriptor?")
.distance_from(requested_descriptor);
Some((self.data(), distance))
} else {
None
}
}
None => None,
}
}

fn instantiate(&mut self, font_context: &FontContextHandle) -> Result<(), ()> {
if !self.is_valid {
return Err(())
}

let data = self.data();
let handle: Result<FontHandle, ()> = FontHandleMethods::new_from_template(font_context,
data,
None);
self.is_valid = handle.is_ok();
let handle = try!(handle);
self.descriptor = Some(FontTemplateDescriptor::new(handle.boldness(),
handle.stretchiness(),
handle.is_italic()));
Ok(())
}


pub fn get(&mut self) -> Option<Arc<FontTemplateData>> {
if self.is_valid {
Expand Down
24 changes: 14 additions & 10 deletions servo/components/gfx/platform/macos/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,20 @@ impl FontHandleMethods for FontHandle {

fn boldness(&self) -> font_weight::T {
let normalized = self.ctfont.all_traits().normalized_weight();
let normalized = (normalized + 1.0) / 2.0 * 9.0;
match normalized {
v if v < 1.0 => font_weight::T::Weight100,
v if v < 2.0 => font_weight::T::Weight200,
v if v < 3.0 => font_weight::T::Weight300,
v if v < 4.0 => font_weight::T::Weight400,
v if v < 5.0 => font_weight::T::Weight500,
v if v < 6.0 => font_weight::T::Weight600,
v if v < 7.0 => font_weight::T::Weight700,
v if v < 8.0 => font_weight::T::Weight800,
let normalized = if normalized <= 0.0 {
4.0 + normalized * 3.0
} else {
4.0 + normalized * 5.0
};
match normalized.round() as u32 {
1 => font_weight::T::Weight100,
2 => font_weight::T::Weight200,
3 => font_weight::T::Weight300,
4 => font_weight::T::Weight400,
5 => font_weight::T::Weight500,
6 => font_weight::T::Weight600,
7 => font_weight::T::Weight700,
8 => font_weight::T::Weight800,
_ => font_weight::T::Weight900,
}
}
Expand Down

0 comments on commit 99d1ef4

Please sign in to comment.