mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
auto merge of #1455 : SimonSapin/servo/font-style, r=kmcallister
* Using .connect(", ") just to use .split(",") later is silly. Keep it a vector. * The 'font-style' property can not be both italic and oblique. Use an enum instead of two booleans.
This commit is contained in:
commit
9340b1892d
7 changed files with 77 additions and 83 deletions
|
@ -15,7 +15,7 @@ use std::rc::RcMut;
|
||||||
use servo_util::cache::{Cache, HashCache};
|
use servo_util::cache::{Cache, HashCache};
|
||||||
use servo_util::range::Range;
|
use servo_util::range::Range;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use style::computed_values::{text_decoration, font_weight};
|
use style::computed_values::{text_decoration, font_weight, font_style};
|
||||||
|
|
||||||
use color::Color;
|
use color::Color;
|
||||||
use font_context::FontContext;
|
use font_context::FontContext;
|
||||||
|
@ -100,9 +100,8 @@ pub struct FontMetrics {
|
||||||
pub struct FontStyle {
|
pub struct FontStyle {
|
||||||
pt_size: f64,
|
pt_size: f64,
|
||||||
weight: font_weight::T,
|
weight: font_weight::T,
|
||||||
italic: bool,
|
style: font_style::T,
|
||||||
oblique: bool,
|
families: ~[~str],
|
||||||
families: ~str,
|
|
||||||
// TODO(Issue #198): font-stretch, text-decoration, font-variant, size-adjust
|
// TODO(Issue #198): font-stretch, text-decoration, font-variant, size-adjust
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +149,7 @@ pub enum FontSelector {
|
||||||
// The ordering of font instances is mainly decided by the CSS
|
// The ordering of font instances is mainly decided by the CSS
|
||||||
// 'font-family' property. The last font is a system fallback font.
|
// 'font-family' property. The last font is a system fallback font.
|
||||||
pub struct FontGroup {
|
pub struct FontGroup {
|
||||||
families: ~str,
|
families: ~[~str],
|
||||||
// style of the first western font in group, which is
|
// style of the first western font in group, which is
|
||||||
// used for purposes of calculating text run metrics.
|
// used for purposes of calculating text run metrics.
|
||||||
style: UsedFontStyle,
|
style: UsedFontStyle,
|
||||||
|
@ -158,7 +157,7 @@ pub struct FontGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontGroup {
|
impl FontGroup {
|
||||||
pub fn new(families: ~str, style: &UsedFontStyle, fonts: ~[RcMut<Font>]) -> FontGroup {
|
pub fn new(families: ~[~str], style: &UsedFontStyle, fonts: ~[RcMut<Font>]) -> FontGroup {
|
||||||
FontGroup {
|
FontGroup {
|
||||||
families: families,
|
families: families,
|
||||||
style: (*style).clone(),
|
style: (*style).clone(),
|
||||||
|
@ -199,7 +198,7 @@ impl RunMetrics {
|
||||||
// ascent+descent and advance is sometimes too generous and
|
// ascent+descent and advance is sometimes too generous and
|
||||||
// looking at actual glyph extents can yield a tighter box.
|
// looking at actual glyph extents can yield a tighter box.
|
||||||
|
|
||||||
RunMetrics {
|
RunMetrics {
|
||||||
advance_width: advance,
|
advance_width: advance,
|
||||||
bounding_box: bounds,
|
bounding_box: bounds,
|
||||||
ascent: ascent,
|
ascent: ascent,
|
||||||
|
@ -288,9 +287,9 @@ impl<'self> Font {
|
||||||
fn make_shaper(&'self mut self) -> &'self Shaper {
|
fn make_shaper(&'self mut self) -> &'self Shaper {
|
||||||
// fast path: already created a shaper
|
// fast path: already created a shaper
|
||||||
match self.shaper {
|
match self.shaper {
|
||||||
Some(ref shaper) => {
|
Some(ref shaper) => {
|
||||||
let s: &'self Shaper = shaper;
|
let s: &'self Shaper = shaper;
|
||||||
return s;
|
return s;
|
||||||
},
|
},
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
@ -401,7 +400,7 @@ impl Font {
|
||||||
|
|
||||||
let glyphbuf = struct__AzGlyphBuffer {
|
let glyphbuf = struct__AzGlyphBuffer {
|
||||||
mGlyphs: vec::raw::to_ptr(azglyphs),
|
mGlyphs: vec::raw::to_ptr(azglyphs),
|
||||||
mNumGlyphs: azglyph_buf_len as uint32_t
|
mNumGlyphs: azglyph_buf_len as uint32_t
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl<'self> FontContext {
|
||||||
profiler_chan: ProfilerChan)
|
profiler_chan: ProfilerChan)
|
||||||
-> FontContext {
|
-> FontContext {
|
||||||
let handle = FontContextHandle::new();
|
let handle = FontContextHandle::new();
|
||||||
let font_list = if needs_font_list {
|
let font_list = if needs_font_list {
|
||||||
Some(FontList::new(&handle, profiler_chan.clone())) }
|
Some(FontList::new(&handle, profiler_chan.clone())) }
|
||||||
else { None };
|
else { None };
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ impl<'self> FontContext {
|
||||||
generic_fonts.insert(~"fantasy", ~"Papyrus");
|
generic_fonts.insert(~"fantasy", ~"Papyrus");
|
||||||
generic_fonts.insert(~"monospace", ~"Menlo");
|
generic_fonts.insert(~"monospace", ~"Menlo");
|
||||||
|
|
||||||
FontContext {
|
FontContext {
|
||||||
instance_cache: LRUCache::new(10),
|
instance_cache: LRUCache::new(10),
|
||||||
font_list: font_list,
|
font_list: font_list,
|
||||||
group_cache: LRUCache::new(10),
|
group_cache: LRUCache::new(10),
|
||||||
|
@ -86,7 +86,7 @@ impl<'self> FontContext {
|
||||||
debug!("font cache hit");
|
debug!("font cache hit");
|
||||||
Ok(f)
|
Ok(f)
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
debug!("font cache miss");
|
debug!("font cache miss");
|
||||||
let result = self.create_font_instance(desc);
|
let result = self.create_font_instance(desc);
|
||||||
match result.clone() {
|
match result.clone() {
|
||||||
|
@ -99,12 +99,10 @@ impl<'self> FontContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_family(&self, family: &str) -> ~str {
|
fn transform_family(&self, family: &~str) -> ~str {
|
||||||
// FIXME: Need a find_like() in HashMap.
|
debug!("(transform family) searching for `{:s}`", family.as_slice());
|
||||||
let family = family.to_str();
|
match self.generic_fonts.find(family) {
|
||||||
debug!("(transform family) searching for `{:s}`", family);
|
None => family.to_owned(),
|
||||||
match self.generic_fonts.find(&family) {
|
|
||||||
None => family,
|
|
||||||
Some(mapped_family) => (*mapped_family).clone()
|
Some(mapped_family) => (*mapped_family).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,9 +113,8 @@ impl<'self> FontContext {
|
||||||
debug!("(create font group) --- starting ---");
|
debug!("(create font group) --- starting ---");
|
||||||
|
|
||||||
// TODO(Issue #193): make iteration over 'font-family' more robust.
|
// TODO(Issue #193): make iteration over 'font-family' more robust.
|
||||||
for family in style.families.split_iter(',') {
|
for family in style.families.iter() {
|
||||||
let family_name = family.trim();
|
let transformed_family_name = self.transform_family(family);
|
||||||
let transformed_family_name = self.transform_family(family_name);
|
|
||||||
debug!("(create font group) transformed family is `{:s}`", transformed_family_name);
|
debug!("(create font group) transformed family is `{:s}`", transformed_family_name);
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
|
|
||||||
|
@ -145,7 +142,7 @@ impl<'self> FontContext {
|
||||||
let instance = self.get_font_by_descriptor(result);
|
let instance = self.get_font_by_descriptor(result);
|
||||||
|
|
||||||
for font in instance.iter() { fonts.push(font.clone()); }
|
for font in instance.iter() { fonts.push(font.clone()); }
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,13 +194,13 @@ impl<'self> FontContext {
|
||||||
|
|
||||||
debug!("(create font group) --- finished ---");
|
debug!("(create font group) --- finished ---");
|
||||||
|
|
||||||
unsafe { RcMut::new_unchecked(FontGroup::new(style.families.to_owned(), &used_style, fonts)) }
|
unsafe { RcMut::new_unchecked(FontGroup::new(style.families.clone(), &used_style, fonts)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
|
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
|
||||||
return match &desc.selector {
|
return match &desc.selector {
|
||||||
// TODO(Issue #174): implement by-platform-name font selectors.
|
// TODO(Issue #174): implement by-platform-name font selectors.
|
||||||
&SelectorPlatformIdentifier(ref identifier) => {
|
&SelectorPlatformIdentifier(ref identifier) => {
|
||||||
let result_handle = self.handle.create_font_from_identifier((*identifier).clone(),
|
let result_handle = self.handle.create_font_from_identifier((*identifier).clone(),
|
||||||
desc.style.clone());
|
desc.style.clone());
|
||||||
do result_handle.and_then |handle| {
|
do result_handle.and_then |handle| {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use platform::font_list::FontListHandle;
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
use servo_util::time::profile;
|
use servo_util::time::profile;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use style::computed_values::font_weight;
|
use style::computed_values::{font_weight, font_style};
|
||||||
|
|
||||||
use std::hashmap::HashMap;
|
use std::hashmap::HashMap;
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ impl<'self> FontList {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_font_in_family(&'self mut self,
|
pub fn find_font_in_family(&'self mut self,
|
||||||
family_name: &~str,
|
family_name: &~str,
|
||||||
style: &SpecifiedFontStyle) -> Option<&'self FontEntry> {
|
style: &SpecifiedFontStyle) -> Option<&'self FontEntry> {
|
||||||
// TODO(Issue #188): look up localized font family names if canonical name not found
|
// TODO(Issue #188): look up localized font family names if canonical name not found
|
||||||
// look up canonical name
|
// look up canonical name
|
||||||
|
@ -82,7 +82,7 @@ impl<'self> FontList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Holds a specific font family, and the various
|
// Holds a specific font family, and the various
|
||||||
pub struct FontFamily<'self> {
|
pub struct FontFamily<'self> {
|
||||||
family_name: ~str,
|
family_name: ~str,
|
||||||
entries: ~[FontEntry],
|
entries: ~[FontEntry],
|
||||||
|
@ -115,8 +115,8 @@ impl<'self> FontFamily {
|
||||||
// TODO(Issue #190): if not in the fast path above, do
|
// TODO(Issue #190): if not in the fast path above, do
|
||||||
// expensive matching of weights, etc.
|
// expensive matching of weights, etc.
|
||||||
for entry in self.entries.iter() {
|
for entry in self.entries.iter() {
|
||||||
if (style.weight.is_bold() == entry.is_bold()) &&
|
if (style.weight.is_bold() == entry.is_bold()) &&
|
||||||
(style.italic == entry.is_italic()) {
|
((style.style == font_style::italic) == entry.is_italic()) {
|
||||||
|
|
||||||
return Some(entry);
|
return Some(entry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@ use fontconfig::fontconfig::{
|
||||||
FcObjectSetAdd, FcPatternGetInteger
|
FcObjectSetAdd, FcPatternGetInteger
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use style::computed_values::font_style;
|
||||||
|
|
||||||
|
|
||||||
use font::{FontHandleMethods, UsedFontStyle};
|
use font::{FontHandleMethods, UsedFontStyle};
|
||||||
use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
||||||
|
@ -163,23 +165,25 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if style.italic {
|
match style.style {
|
||||||
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
font_style::normal => (),
|
||||||
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
|
font_style::italic => {
|
||||||
};
|
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
||||||
if res != 1 {
|
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
|
||||||
debug!("adding slant(italic) to pattern failed");
|
};
|
||||||
return Err(());
|
if res != 1 {
|
||||||
}
|
debug!("adding slant to pattern failed");
|
||||||
}
|
return Err(());
|
||||||
|
}
|
||||||
if style.oblique {
|
},
|
||||||
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
font_style::oblique => {
|
||||||
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
|
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
||||||
};
|
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
|
||||||
if res != 1 {
|
};
|
||||||
debug!("adding slant(oblique) to pattern failed");
|
if res != 1 {
|
||||||
return Err(());
|
debug!("adding slant(oblique) to pattern failed");
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ use fontconfig::fontconfig::{
|
||||||
FcObjectSetAdd, FcPatternGetInteger
|
FcObjectSetAdd, FcPatternGetInteger
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use style::computed_values::font_style;
|
||||||
|
|
||||||
|
|
||||||
use font::{FontHandleMethods, UsedFontStyle};
|
use font::{FontHandleMethods, UsedFontStyle};
|
||||||
use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
use font_list::{FontEntry, FontFamily, FontFamilyMap};
|
||||||
|
@ -163,23 +165,25 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if style.italic {
|
match style.style {
|
||||||
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
font_style::normal => (),
|
||||||
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
|
font_style::italic => {
|
||||||
};
|
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
||||||
if res != 1 {
|
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
|
||||||
debug!("adding slant(italic) to pattern failed");
|
};
|
||||||
return Err(());
|
if res != 1 {
|
||||||
}
|
debug!("adding slant to pattern failed");
|
||||||
}
|
return Err(());
|
||||||
|
}
|
||||||
if style.oblique {
|
},
|
||||||
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
font_style::oblique => {
|
||||||
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
|
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
|
||||||
};
|
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
|
||||||
if res != 1 {
|
};
|
||||||
debug!("adding slant(oblique) to pattern failed");
|
if res != 1 {
|
||||||
return Err(());
|
debug!("adding slant(oblique) to pattern failed");
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ use std::cmp::ApproxEq;
|
||||||
use std::num::Zero;
|
use std::num::Zero;
|
||||||
use style::{ComputedValues, TElement, TNode};
|
use style::{ComputedValues, TElement, TNode};
|
||||||
use style::computed_values::{LengthOrPercentage, overflow};
|
use style::computed_values::{LengthOrPercentage, overflow};
|
||||||
use style::computed_values::{border_style, clear, font_family, font_style, line_height};
|
use style::computed_values::{border_style, clear, font_family, line_height};
|
||||||
use style::computed_values::{text_align, text_decoration, vertical_align, visibility};
|
use style::computed_values::{text_align, text_decoration, vertical_align, visibility};
|
||||||
|
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
|
@ -404,25 +404,15 @@ impl Box {
|
||||||
font_family::FamilyName(ref name) => (*name).clone(),
|
font_family::FamilyName(ref name) => (*name).clone(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let font_families = font_families.connect(", ");
|
debug!("(font style) font families: `{:?}`", font_families);
|
||||||
debug!("(font style) font families: `{:s}`", font_families);
|
|
||||||
|
|
||||||
let font_size = my_style.Font.font_size.to_f64().unwrap() / 60.0;
|
let font_size = my_style.Font.font_size.to_f64().unwrap() / 60.0;
|
||||||
debug!("(font style) font size: `{:f}px`", font_size);
|
debug!("(font style) font size: `{:f}px`", font_size);
|
||||||
|
|
||||||
let (italic, oblique) = match my_style.Font.font_style {
|
|
||||||
font_style::normal => (false, false),
|
|
||||||
font_style::italic => (true, false),
|
|
||||||
font_style::oblique => (false, true),
|
|
||||||
};
|
|
||||||
|
|
||||||
let font_weight = my_style.Font.font_weight;
|
|
||||||
|
|
||||||
FontStyle {
|
FontStyle {
|
||||||
pt_size: font_size,
|
pt_size: font_size,
|
||||||
weight: font_weight,
|
weight: my_style.Font.font_weight,
|
||||||
italic: italic,
|
style: my_style.Font.font_style,
|
||||||
oblique: oblique,
|
|
||||||
families: font_families,
|
families: font_families,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ pub mod longhands {
|
||||||
match component_value {
|
match component_value {
|
||||||
&Ident(ref value) => {
|
&Ident(ref value) => {
|
||||||
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
||||||
let value_lower = value.to_ascii_lower();
|
let value_lower = value.to_ascii_lower();
|
||||||
match value_lower.as_slice() {
|
match value_lower.as_slice() {
|
||||||
"thin" => Some(specified::Length::from_px(1.)),
|
"thin" => Some(specified::Length::from_px(1.)),
|
||||||
"medium" => Some(specified::Length::from_px(3.)),
|
"medium" => Some(specified::Length::from_px(3.)),
|
||||||
|
@ -236,7 +236,7 @@ pub mod longhands {
|
||||||
|
|
||||||
// TODO: don't parse values we don't support
|
// TODO: don't parse values we don't support
|
||||||
<%self:single_keyword_computed name="display"
|
<%self:single_keyword_computed name="display"
|
||||||
values="inline block inline-block
|
values="inline block inline-block
|
||||||
table inline-table table-row-group table-header-group table-footer-group
|
table inline-table table-row-group table-header-group table-footer-group
|
||||||
table-row table-column-group table-column table-cell table-caption
|
table-row table-column-group table-column table-cell table-caption
|
||||||
list-item
|
list-item
|
||||||
|
@ -346,7 +346,7 @@ pub mod longhands {
|
||||||
match input {
|
match input {
|
||||||
&Ident(ref value) => {
|
&Ident(ref value) => {
|
||||||
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
||||||
let value_lower = value.to_ascii_lower();
|
let value_lower = value.to_ascii_lower();
|
||||||
match value_lower.as_slice() {
|
match value_lower.as_slice() {
|
||||||
% for keyword in vertical_align_keywords:
|
% for keyword in vertical_align_keywords:
|
||||||
"${keyword}" => Some(Specified_${to_rust_ident(keyword)}),
|
"${keyword}" => Some(Specified_${to_rust_ident(keyword)}),
|
||||||
|
@ -472,7 +472,7 @@ pub mod longhands {
|
||||||
Some(&Ident(ref value)) => {
|
Some(&Ident(ref value)) => {
|
||||||
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
||||||
let value = value.as_slice();
|
let value = value.as_slice();
|
||||||
let value_lower = value.to_ascii_lower();
|
let value_lower = value.to_ascii_lower();
|
||||||
match value_lower.as_slice() {
|
match value_lower.as_slice() {
|
||||||
// "serif" => add!(Serif),
|
// "serif" => add!(Serif),
|
||||||
// "sans-serif" => add!(SansSerif),
|
// "sans-serif" => add!(SansSerif),
|
||||||
|
@ -523,7 +523,7 @@ pub mod longhands {
|
||||||
match input {
|
match input {
|
||||||
&Ident(ref value) => {
|
&Ident(ref value) => {
|
||||||
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
|
||||||
let value_lower = value.to_ascii_lower();
|
let value_lower = value.to_ascii_lower();
|
||||||
match value_lower.as_slice() {
|
match value_lower.as_slice() {
|
||||||
"bold" => Some(SpecifiedWeight700),
|
"bold" => Some(SpecifiedWeight700),
|
||||||
"normal" => Some(SpecifiedWeight400),
|
"normal" => Some(SpecifiedWeight400),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue