Add support for small-caps font-variant.

Ref: 2554.
This commit is contained in:
Glenn Watson 2014-09-23 14:21:41 +10:00
parent 6177a3bdcc
commit 0dd1b85739
7 changed files with 32 additions and 14 deletions

View file

@ -634,7 +634,7 @@ impl DisplayItem {
render_context.font_ctx.get_render_font_from_template( render_context.font_ctx.get_render_font_from_template(
&text.text_run.font_template, &text.text_run.font_template,
text.text_run.pt_size, text.text_run.actual_pt_size,
render_context.opts.render_backend render_context.opts.render_backend
).borrow().draw_text_into_context( ).borrow().draw_text_into_context(
render_context, render_context,

View file

@ -8,7 +8,7 @@ use std::string;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use servo_util::cache::{Cache, HashCache}; use servo_util::cache::{Cache, HashCache};
use style::computed_values::{font_weight, font_style}; use style::computed_values::{font_weight, font_style, font_variant};
use sync::Arc; use sync::Arc;
use servo_util::geometry::Au; use servo_util::geometry::Au;
@ -93,7 +93,8 @@ pub struct FontStyle {
pub weight: font_weight::T, pub weight: font_weight::T,
pub style: font_style::T, pub style: font_style::T,
pub families: Vec<String>, pub families: Vec<String>,
// TODO(Issue #198): font-stretch, text-decoration, font-variant, size-adjust pub variant: font_variant::T,
// TODO(Issue #198): font-stretch, text-decoration, size-adjust
} }
pub type SpecifiedFontStyle = FontStyle; pub type SpecifiedFontStyle = FontStyle;
@ -102,8 +103,10 @@ pub type UsedFontStyle = FontStyle;
pub struct Font { pub struct Font {
pub handle: FontHandle, pub handle: FontHandle,
pub metrics: FontMetrics, pub metrics: FontMetrics,
pub variant: font_variant::T,
pub descriptor: FontTemplateDescriptor, pub descriptor: FontTemplateDescriptor,
pub pt_size: f64, pub requested_pt_size: f64,
pub actual_pt_size: f64,
pub shaper: Option<Shaper>, pub shaper: Option<Shaper>,
pub shape_cache: HashCache<String, Arc<GlyphStore>>, pub shape_cache: HashCache<String, Arc<GlyphStore>>,
pub glyph_advance_cache: HashCache<u32, FractionalPixel>, pub glyph_advance_cache: HashCache<u32, FractionalPixel>,
@ -147,6 +150,10 @@ impl Font {
} }
pub fn glyph_index(&self, codepoint: char) -> Option<GlyphId> { pub fn glyph_index(&self, codepoint: char) -> Option<GlyphId> {
let codepoint = match self.variant {
font_variant::small_caps => codepoint.to_uppercase(),
font_variant::normal => codepoint,
};
self.handle.glyph_index(codepoint) self.handle.glyph_index(codepoint)
} }

View file

@ -5,7 +5,7 @@
use font::{Font, FontGroup}; use font::{Font, FontGroup};
use font::SpecifiedFontStyle; use font::SpecifiedFontStyle;
use platform::font_context::FontContextHandle; use platform::font_context::FontContextHandle;
use style::computed_values::font_style; use style::computed_values::{font_style, font_variant};
use font_cache_task::FontCacheTask; use font_cache_task::FontCacheTask;
use font_template::FontTemplateDescriptor; use font_template::FontTemplateDescriptor;
@ -80,16 +80,24 @@ impl FontContext {
/// Create a font for use in layout calculations. /// Create a font for use in layout calculations.
fn create_layout_font(&self, template: Arc<FontTemplateData>, fn create_layout_font(&self, template: Arc<FontTemplateData>,
descriptor: FontTemplateDescriptor, pt_size: f64) -> Font { descriptor: FontTemplateDescriptor, pt_size: f64,
variant: font_variant::T) -> Font {
let actual_pt_size = match variant {
font_variant::small_caps => pt_size * 0.7,
font_variant::normal => pt_size,
};
let handle: FontHandle = FontHandleMethods::new_from_template(&self.platform_handle, template, Some(pt_size)).unwrap(); let handle: FontHandle = FontHandleMethods::new_from_template(&self.platform_handle,
template, Some(actual_pt_size)).unwrap();
let metrics = handle.get_metrics(); let metrics = handle.get_metrics();
Font { Font {
handle: handle, handle: handle,
shaper: None, shaper: None,
variant: variant,
descriptor: descriptor, descriptor: descriptor,
pt_size: pt_size, requested_pt_size: pt_size,
actual_pt_size: actual_pt_size,
metrics: metrics, metrics: metrics,
shape_cache: HashCache::new(), shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(), glyph_advance_cache: HashCache::new(),
@ -114,7 +122,8 @@ impl FontContext {
if cached_font_entry.family == *family { if cached_font_entry.family == *family {
let cached_font = cached_font_entry.font.borrow(); let cached_font = cached_font_entry.font.borrow();
if cached_font.descriptor == desc && if cached_font.descriptor == desc &&
cached_font.pt_size == style.pt_size { cached_font.requested_pt_size == style.pt_size &&
cached_font.variant == style.variant {
fonts.push(cached_font_entry.font.clone()); fonts.push(cached_font_entry.font.clone());
cache_hit = true; cache_hit = true;
break; break;
@ -124,7 +133,8 @@ impl FontContext {
if !cache_hit { if !cache_hit {
let font_template = self.font_cache_task.get_font_template(family.clone(), desc.clone()); let font_template = self.font_cache_task.get_font_template(family.clone(), desc.clone());
let layout_font = Rc::new(RefCell::new(self.create_layout_font(font_template, desc.clone(), style.pt_size))); let layout_font = Rc::new(RefCell::new(self.create_layout_font(font_template,
desc.clone(), style.pt_size, style.variant)));
self.layout_font_cache.push(LayoutFontCacheEntry { self.layout_font_cache.push(LayoutFontCacheEntry {
family: family.clone(), family: family.clone(),
font: layout_font.clone(), font: layout_font.clone(),

View file

@ -164,7 +164,7 @@ impl Shaper {
let hb_font: *mut hb_font_t = hb_font_create(hb_face); let hb_font: *mut hb_font_t = hb_font_create(hb_face);
// Set points-per-em. if zero, performs no hinting in that direction. // Set points-per-em. if zero, performs no hinting in that direction.
let pt_size = font.pt_size; let pt_size = font.actual_pt_size;
hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint); hb_font_set_ppem(hb_font, pt_size as c_uint, pt_size as c_uint);
// Set scaling. Note that this takes 16.16 fixed point. // Set scaling. Note that this takes 16.16 fixed point.

View file

@ -17,7 +17,7 @@ use platform::font_template::FontTemplateData;
pub struct TextRun { pub struct TextRun {
pub text: Arc<String>, pub text: Arc<String>,
pub font_template: Arc<FontTemplateData>, pub font_template: Arc<FontTemplateData>,
pub pt_size: f64, pub actual_pt_size: f64,
pub font_metrics: FontMetrics, pub font_metrics: FontMetrics,
/// The glyph runs that make up this text run. /// The glyph runs that make up this text run.
pub glyphs: Arc<Vec<GlyphRun>>, pub glyphs: Arc<Vec<GlyphRun>>,
@ -123,7 +123,7 @@ impl<'a> TextRun {
text: Arc::new(text), text: Arc::new(text),
font_metrics: font.metrics.clone(), font_metrics: font.metrics.clone(),
font_template: font.handle.get_template(), font_template: font.handle.get_template(),
pt_size: font.pt_size, actual_pt_size: font.actual_pt_size,
glyphs: Arc::new(glyphs), glyphs: Arc::new(glyphs),
}; };
return run; return run;

View file

@ -309,6 +309,7 @@ pub fn computed_style_to_font_style(style: &ComputedValues) -> FontStyle {
pt_size: font_size, pt_size: font_size,
weight: style.get_font().font_weight, weight: style.get_font().font_weight,
style: style.get_font().font_style, style: style.get_font().font_style,
variant: style.get_font().font_variant,
families: font_families.collect(), families: font_families.collect(),
} }
} }

View file

@ -802,7 +802,7 @@ pub mod longhands {
${single_keyword("font-style", "normal italic oblique")} ${single_keyword("font-style", "normal italic oblique")}
${single_keyword("font-variant", "normal")} // Add small-caps when supported ${single_keyword("font-variant", "normal small-caps")}
<%self:single_component_value name="font-weight"> <%self:single_component_value name="font-weight">
#[deriving(Clone)] #[deriving(Clone)]