servo: Merge #4524 - gfx: Implement `font-stretch` per CSS3-FONTS § 3.3 in the Core Text font backend (from pcwalton:font-stretch); r=glennw

r? @glennw

Source-Repo: https://github.com/servo/servo
Source-Revision: 3736396c63ad3f84349132ea9c0bb0f5fc045f01
This commit is contained in:
Patrick Walton 2015-01-28 13:57:58 -07:00
Родитель 39a22519e3
Коммит c36f083a85
8 изменённых файлов: 101 добавлений и 44 удалений

Просмотреть файл

@ -10,7 +10,7 @@ use std::rc::Rc;
use std::cell::RefCell;
use servo_util::cache::HashCache;
use servo_util::smallvec::{SmallVec, SmallVec8};
use style::computed_values::{font_variant, font_weight};
use style::computed_values::{font_stretch, font_variant, font_weight};
use style::style_structs::Font as FontStyle;
use std::sync::Arc;
@ -37,6 +37,7 @@ pub trait FontHandleMethods {
fn face_name(&self) -> String;
fn is_italic(&self) -> bool;
fn boldness(&self) -> font_weight::T;
fn stretchiness(&self) -> font_stretch::T;
fn glyph_index(&self, codepoint: char) -> Option<GlyphId>;
fn glyph_h_advance(&self, GlyphId) -> Option<FractionalPixel>;

Просмотреть файл

@ -140,7 +140,9 @@ impl FontContext {
// so they will never be released. Find out a good time to drop them.
let desc = FontTemplateDescriptor::new(style.font_weight,
style.font_style == font_style::T::italic || style.font_style == font_style::T::oblique);
style.font_stretch,
style.font_style == font_style::T::italic ||
style.font_style == font_style::T::oblique);
let mut fonts = SmallVec8::new();
for family in style.font_family.iter() {

Просмотреть файл

@ -2,14 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use style::computed_values::font_weight;
use font::FontHandleMethods;
use platform::font_context::FontContextHandle;
use platform::font::FontHandle;
use platform::font_template::FontTemplateData;
use std::borrow::ToOwned;
use std::sync::{Arc, Weak};
use font::FontHandleMethods;
use style::computed_values::{font_stretch, font_weight};
/// Describes how to select a font from a given family.
/// This is very basic at the moment and needs to be
@ -18,13 +18,17 @@ use font::FontHandleMethods;
#[derive(Clone, Copy)]
pub struct FontTemplateDescriptor {
pub weight: font_weight::T,
pub stretch: font_stretch::T,
pub italic: bool,
}
impl FontTemplateDescriptor {
pub fn new(weight: font_weight::T, italic: bool) -> FontTemplateDescriptor {
#[inline]
pub fn new(weight: font_weight::T, stretch: font_stretch::T, italic: bool)
-> FontTemplateDescriptor {
FontTemplateDescriptor {
weight: weight,
stretch: stretch,
italic: italic,
}
}
@ -33,7 +37,8 @@ impl FontTemplateDescriptor {
impl PartialEq for FontTemplateDescriptor {
fn eq(&self, other: &FontTemplateDescriptor) -> bool {
self.weight.is_bold() == other.weight.is_bold() &&
self.italic == other.italic
self.stretch == other.stretch &&
self.italic == other.italic
}
}
@ -44,7 +49,8 @@ pub struct FontTemplate {
identifier: String,
descriptor: Option<FontTemplateDescriptor>,
weak_ref: Option<Weak<FontTemplateData>>,
strong_ref: Option<Arc<FontTemplateData>>, // GWTODO: Add code path to unset the strong_ref for web fonts!
// GWTODO: Add code path to unset the strong_ref for web fonts!
strong_ref: Option<Arc<FontTemplateData>>,
is_valid: bool,
}
@ -82,8 +88,10 @@ impl FontTemplate {
}
/// Get the data for creating a font if it matches a given descriptor.
pub fn get_if_matches(&mut self, fctx: &FontContextHandle,
requested_desc: &FontTemplateDescriptor) -> Option<Arc<FontTemplateData>> {
pub fn get_if_matches(&mut self,
fctx: &FontContextHandle,
requested_desc: &FontTemplateDescriptor)
-> Option<Arc<FontTemplateData>> {
// The font template data can be unloaded when nothing is referencing
// it (via the Weak reference to the Arc above). However, if we have
// already loaded a font, store the style information about it separately,
@ -97,42 +105,42 @@ impl FontTemplate {
None
}
},
None => {
if self.is_valid {
let data = self.get_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.is_italic());
let desc_match = actual_desc == *requested_desc;
None if self.is_valid => {
let data = self.get_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);
self.descriptor = Some(actual_desc);
self.is_valid = true;
if desc_match {
Some(data)
} else {
None
}
}
} else {
None
Err(()) => {
self.is_valid = false;
debug!("Unable to create a font from template {}", self.identifier);
None
}
}
}
None => None,
}
}
/// Get the data for creating a font.
pub fn get(&mut self) -> Option<Arc<FontTemplateData>> {
match self.is_valid {
true => Some(self.get_data()),
false => None
if self.is_valid {
Some(self.get_data())
} else {
None
}
}
@ -145,14 +153,13 @@ impl FontTemplate {
None => None,
};
match maybe_data {
Some(data) => data,
None => {
assert!(self.strong_ref.is_none());
let template_data = Arc::new(FontTemplateData::new(self.identifier.as_slice(), None));
self.weak_ref = Some(template_data.downgrade());
template_data
}
if let Some(data) = maybe_data {
return data
}
assert!(self.strong_ref.is_none());
let template_data = Arc::new(FontTemplateData::new(self.identifier.as_slice(), None));
self.weak_ref = Some(template_data.downgrade());
template_data
}
}

Просмотреть файл

@ -12,7 +12,7 @@ use servo_util::str::c_str_to_string;
use platform::font_context::FontContextHandle;
use text::glyph::GlyphId;
use text::util::{float_to_fixed, fixed_to_float};
use style::computed_values::font_weight;
use style::computed_values::{font_stretch, font_weight};
use platform::font_template::FontTemplateData;
use freetype::freetype::{FT_Get_Char_Index, FT_Get_Postscript_Name};
@ -161,6 +161,10 @@ impl FontHandleMethods for FontHandle {
}
}
}
fn stretchiness(&self) -> font_stretch::T {
// TODO(pcwalton): Implement this.
font_stretch::T::normal
}
fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
assert!(!self.face.is_null());

Просмотреть файл

@ -15,7 +15,7 @@ use servo_util::geometry::{Au, px_to_pt};
use servo_util::geometry;
use platform::macos::font_context::FontContextHandle;
use text::glyph::GlyphId;
use style::computed_values::font_weight;
use style::computed_values::{font_stretch, font_weight};
use platform::font_template::FontTemplateData;
use core_foundation::base::CFIndex;
@ -111,6 +111,21 @@ impl FontHandleMethods for FontHandle {
return font_weight::T::Weight900;
}
fn stretchiness(&self) -> font_stretch::T {
let normalized = self.ctfont.all_traits().normalized_width(); // [-1.0, 1.0]
match (normalized + 1.0) / 2.0 * 9.0 { // [0.0, 9.0]
v if v < 1.0 => font_stretch::T::ultra_condensed,
v if v < 2.0 => font_stretch::T::extra_condensed,
v if v < 3.0 => font_stretch::T::condensed,
v if v < 4.0 => font_stretch::T::semi_condensed,
v if v < 5.0 => font_stretch::T::normal,
v if v < 6.0 => font_stretch::T::semi_expanded,
v if v < 7.0 => font_stretch::T::expanded,
v if v < 8.0 => font_stretch::T::extra_expanded,
_ => font_stretch::T::ultra_expanded,
}
}
fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
let characters: [UniChar; 1] = [codepoint as UniChar];
let mut glyphs: [CGGlyph; 1] = [0 as CGGlyph];

Просмотреть файл

@ -127,6 +127,7 @@ partial interface CSSStyleDeclaration {
[TreatNullAs=EmptyString] attribute DOMString font;
[TreatNullAs=EmptyString] attribute DOMString fontFamily;
[TreatNullAs=EmptyString] attribute DOMString fontSize;
[TreatNullAs=EmptyString] attribute DOMString fontStretch;
[TreatNullAs=EmptyString] attribute DOMString fontStyle;
[TreatNullAs=EmptyString] attribute DOMString fontVariant;
[TreatNullAs=EmptyString] attribute DOMString fontWeight;

Просмотреть файл

@ -1149,6 +1149,9 @@ pub mod longhands {
}
</%self:longhand>
${single_keyword("font-stretch",
"normal ultra-condensed extra-condensed condensed semi-condensed semi-expanded expanded extra-expanded ultra-expanded")}
// CSS 2.1, Section 16 - Text
${new_style_struct("InheritedText", is_inherited=True)}

Просмотреть файл

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-size: 36pt;
font-family: "Helvetica Neue";
font-weight: bold;
font-style: normal;
}
#a {
font-stretch: normal;
}
#b {
font-stretch: condensed;
}
</style>
</head>
<body>
<div id=a>Felis silvestris catus</div>
<div id=b>Felis silvestris catus</div>
</body>
</html>