From 0dd1b8573910be7d953169a23bfce36d7a8abb38 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 23 Sep 2014 14:21:41 +1000 Subject: [PATCH] Add support for small-caps font-variant. Ref: 2554. --- components/gfx/display_list/mod.rs | 2 +- components/gfx/font.rs | 13 ++++++++++--- components/gfx/font_context.rs | 22 ++++++++++++++++------ components/gfx/text/shaping/harfbuzz.rs | 2 +- components/gfx/text/text_run.rs | 4 ++-- components/layout/text.rs | 1 + components/style/properties/mod.rs.mako | 2 +- 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index bb274e74672..55829ae78d4 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -634,7 +634,7 @@ impl DisplayItem { render_context.font_ctx.get_render_font_from_template( &text.text_run.font_template, - text.text_run.pt_size, + text.text_run.actual_pt_size, render_context.opts.render_backend ).borrow().draw_text_into_context( render_context, diff --git a/components/gfx/font.rs b/components/gfx/font.rs index 5d4af74d0a9..b3f85edf823 100644 --- a/components/gfx/font.rs +++ b/components/gfx/font.rs @@ -8,7 +8,7 @@ use std::string; use std::rc::Rc; use std::cell::RefCell; 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 servo_util::geometry::Au; @@ -93,7 +93,8 @@ pub struct FontStyle { pub weight: font_weight::T, pub style: font_style::T, pub families: Vec, - // 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; @@ -102,8 +103,10 @@ pub type UsedFontStyle = FontStyle; pub struct Font { pub handle: FontHandle, pub metrics: FontMetrics, + pub variant: font_variant::T, pub descriptor: FontTemplateDescriptor, - pub pt_size: f64, + pub requested_pt_size: f64, + pub actual_pt_size: f64, pub shaper: Option, pub shape_cache: HashCache>, pub glyph_advance_cache: HashCache, @@ -147,6 +150,10 @@ impl Font { } pub fn glyph_index(&self, codepoint: char) -> Option { + let codepoint = match self.variant { + font_variant::small_caps => codepoint.to_uppercase(), + font_variant::normal => codepoint, + }; self.handle.glyph_index(codepoint) } diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs index 3520da107f5..f00a903ffce 100644 --- a/components/gfx/font_context.rs +++ b/components/gfx/font_context.rs @@ -5,7 +5,7 @@ use font::{Font, FontGroup}; use font::SpecifiedFontStyle; 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_template::FontTemplateDescriptor; @@ -80,16 +80,24 @@ impl FontContext { /// Create a font for use in layout calculations. fn create_layout_font(&self, template: Arc, - 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(); Font { handle: handle, shaper: None, + variant: variant, descriptor: descriptor, - pt_size: pt_size, + requested_pt_size: pt_size, + actual_pt_size: actual_pt_size, metrics: metrics, shape_cache: HashCache::new(), glyph_advance_cache: HashCache::new(), @@ -114,7 +122,8 @@ impl FontContext { if cached_font_entry.family == *family { let cached_font = cached_font_entry.font.borrow(); 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()); cache_hit = true; break; @@ -124,7 +133,8 @@ impl FontContext { if !cache_hit { 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 { family: family.clone(), font: layout_font.clone(), diff --git a/components/gfx/text/shaping/harfbuzz.rs b/components/gfx/text/shaping/harfbuzz.rs index f41ea82cf6d..674e5f7bcec 100644 --- a/components/gfx/text/shaping/harfbuzz.rs +++ b/components/gfx/text/shaping/harfbuzz.rs @@ -164,7 +164,7 @@ impl Shaper { let hb_font: *mut hb_font_t = hb_font_create(hb_face); // 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); // Set scaling. Note that this takes 16.16 fixed point. diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index 57ca437e4f2..cdf7e5c9ddf 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -17,7 +17,7 @@ use platform::font_template::FontTemplateData; pub struct TextRun { pub text: Arc, pub font_template: Arc, - pub pt_size: f64, + pub actual_pt_size: f64, pub font_metrics: FontMetrics, /// The glyph runs that make up this text run. pub glyphs: Arc>, @@ -123,7 +123,7 @@ impl<'a> TextRun { text: Arc::new(text), font_metrics: font.metrics.clone(), font_template: font.handle.get_template(), - pt_size: font.pt_size, + actual_pt_size: font.actual_pt_size, glyphs: Arc::new(glyphs), }; return run; diff --git a/components/layout/text.rs b/components/layout/text.rs index e2ab1d545d5..36384e24290 100644 --- a/components/layout/text.rs +++ b/components/layout/text.rs @@ -309,6 +309,7 @@ pub fn computed_style_to_font_style(style: &ComputedValues) -> FontStyle { pt_size: font_size, weight: style.get_font().font_weight, style: style.get_font().font_style, + variant: style.get_font().font_variant, families: font_families.collect(), } } diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index 5f457dfcd49..d45a413caaf 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -802,7 +802,7 @@ pub mod longhands { ${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"> #[deriving(Clone)]