Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First part of font refactoring. These changes simplify a few things #2751

Merged
merged 1 commit into from Jul 3, 2014
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

First part of font refactoring. These changes simplify a few things

but don't do much on their own, they just make it easier to
implement the work to come (web fonts, performance improvments
in terms of font loading and memory usage).

- Font identifier on Linux/Android is now the font file path.
  This is a temporary measure, but simplifies things a lot for now.
- Remove FontListHandleMethods trait in favour of free functions.
- FontList::refresh() has no knowledge of FontFamily etc. Instead it takes
  a closure that the caller provides.
- FontList::load_variations_for_family no longer creates the font
  handle. Instead it takes a closure and provides the name of the font
  identifier for the variations it finds.
- Remove path_from_identifier() - it's no longer required.
- create_font_from_identifier() takes an Option<Style>, allowing it to be
  used to create fonts for family matching purposes where the font size is
  not important.

Tested on Linux + Mac. Builds on Android but not able to confirm it's working correctly.
  • Loading branch information
gw3583 committed Jul 2, 2014
commit 51bd334f3fba1e074d5f51f518e65c8fad2c2928
@@ -30,7 +30,7 @@ pub struct FontContextInfo {
}

pub trait FontContextHandleMethods {
fn create_font_from_identifier(&self, String, UsedFontStyle) -> Result<FontHandle, ()>;
fn create_font_from_identifier(&self, &str, Option<&UsedFontStyle>) -> Result<FontHandle, ()>;
}

pub struct FontContext {
@@ -128,7 +128,7 @@ impl FontContext {

let result = match self.font_list {
Some(ref mut fl) => {
let font_in_family = fl.find_font_in_family(&transformed_family_name, style);
let font_in_family = fl.find_font_in_family(&self.handle, &transformed_family_name, style);
match font_in_family {
Some(font_entry) => {
let font_id =
@@ -164,7 +164,7 @@ impl FontContext {
let font_desc = match self.font_list {
Some(ref mut font_list) => {
let font_desc = {
let font_entry = font_list.find_font_in_family(family, style);
let font_entry = font_list.find_font_in_family(&self.handle, family, style);
match font_entry {
Some(v) => {
let font_id =
@@ -207,8 +207,8 @@ impl FontContext {
return match &desc.selector {
// TODO(Issue #174): implement by-platform-name font selectors.
&SelectorPlatformIdentifier(ref identifier) => {
let result_handle = self.handle.create_font_from_identifier((*identifier).clone(),
desc.style.clone());
let result_handle = self.handle.create_font_from_identifier(identifier.as_slice(),
Some(&desc.style));
result_handle.and_then(|handle| {
Ok(
Rc::new(
@@ -4,37 +4,29 @@

use std::collections::hashmap::HashMap;
use font::SpecifiedFontStyle;
use font_context::FontContextHandleMethods;
use gfx_font::FontHandleMethods;
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use platform::font_list::FontListHandle;
use platform::font_list;
use style::computed_values::{font_weight, font_style};

use servo_util::time::{TimeProfilerChan, profile};
use servo_util::time;

pub type FontFamilyMap = HashMap<String, FontFamily>;

trait FontListHandleMethods {
fn get_available_families(&self, fctx: &FontContextHandle) -> FontFamilyMap;
fn load_variations_for_family(&self, family: &mut FontFamily);
fn get_last_resort_font_families() -> Vec<String>;
}

/// The platform-independent font list abstraction.
pub struct FontList {
family_map: FontFamilyMap,
handle: FontListHandle,
time_profiler_chan: TimeProfilerChan,
}

impl FontList {
pub fn new(fctx: &FontContextHandle,
time_profiler_chan: TimeProfilerChan)
-> FontList {
let handle = FontListHandle::new(fctx);
let mut list = FontList {
handle: handle,
family_map: HashMap::new(),
time_profiler_chan: time_profiler_chan.clone(),
};
@@ -48,11 +40,16 @@ impl FontList {
//
// Should font families with entries be invalidated/refreshed too?
profile(time::GfxRegenAvailableFontsCategory, self.time_profiler_chan.clone(), || {
self.family_map = self.handle.get_available_families();
self.family_map.clear();
font_list::get_available_families(|family_name| {
debug!("Creating new FontFamily for family: {:s}", family_name);
let new_family = FontFamily::new(family_name.as_slice());
self.family_map.insert(family_name, new_family);
});
});
}

pub fn find_font_in_family<'a>(&'a mut self,
pub fn find_font_in_family<'a>(&'a mut self, fctx: &FontContextHandle,
family_name: &String,
style: &SpecifiedFontStyle) -> Option<&'a FontEntry> {
// TODO(Issue #188): look up localized font family names if canonical name not found
@@ -63,7 +60,7 @@ impl FontList {
let s: &'a mut FontFamily = self.family_map.get_mut(family_name);
// TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
// if such family exists, try to match style to a font
let result = s.find_font_for_style(&mut self.handle, style);
let result = s.find_font_for_style(fctx, style);
if result.is_some() {
return result;
}
@@ -76,7 +73,7 @@ impl FontList {
}

pub fn get_last_resort_font_families() -> Vec<String> {
FontListHandle::get_last_resort_font_families()
font_list::get_last_resort_font_families()
}
}

@@ -94,17 +91,24 @@ impl FontFamily {
}
}

fn load_family_variations(&mut self, list: &FontListHandle) {
fn load_family_variations(&mut self, fctx: &FontContextHandle) {
if self.entries.len() > 0 {
return
}
list.load_variations_for_family(self);
let mut entries = vec!();
font_list::load_variations_for_family(self.family_name.as_slice(), |file_path| {
let font_handle = fctx.create_font_from_identifier(file_path.as_slice(), None).unwrap();
debug!("Creating new FontEntry for face: {:s}", font_handle.face_name());
let entry = FontEntry::new(font_handle);
entries.push(entry);
});
self.entries = entries;
assert!(self.entries.len() > 0)
}

pub fn find_font_for_style<'a>(&'a mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
pub fn find_font_for_style<'a>(&'a mut self, fctx: &FontContextHandle, style: &SpecifiedFontStyle)
-> Option<&'a FontEntry> {
self.load_family_variations(list);
self.load_family_variations(fctx);

// TODO(Issue #189): optimize lookup for
// regular/bold/italic/bolditalic with fixed offsets and a
@@ -118,9 +118,11 @@ impl FontHandleMethods for FontHandle {

// an identifier usable by FontContextHandle to recreate this FontHandle.
fn face_identifier(&self) -> String {
/* FT_Get_Postscript_Name seems like a better choice here, but it
doesn't give usable results for fontconfig when deserializing. */
unsafe { str::raw::from_c_str((*self.face).family_name) }
match self.source {
FontSourceFile(ref path) => path.clone(),
_ => unreachable!(), // This will be handled when the rest of the font
// refactor is complete. For now, it can never be hit.
}
}
fn family_name(&self) -> String {
unsafe { str::raw::from_c_str((*self.face).family_name) }
@@ -5,7 +5,6 @@
use font::UsedFontStyle;
use platform::font::FontHandle;
use font_context::FontContextHandleMethods;
use platform::font_list::path_from_identifier;

use freetype::freetype::FTErrorMethods;
use freetype::freetype::FT_Add_Default_Modules;
@@ -65,7 +64,7 @@ impl FontContextHandle {

let ptr = libc::malloc(mem::size_of::<struct_FT_MemoryRec_>() as size_t);
let allocator: &mut struct_FT_MemoryRec_ = mem::transmute(ptr);
mem::overwrite(allocator, struct_FT_MemoryRec_ {
ptr::write(allocator, struct_FT_MemoryRec_ {
user: ptr::null(),
alloc: ft_alloc,
free: ft_free,
@@ -87,13 +86,10 @@ impl FontContextHandle {
}

impl FontContextHandleMethods for FontContextHandle {
fn create_font_from_identifier(&self, name: String, style: UsedFontStyle)
fn create_font_from_identifier(&self, name: &str, style: Option<&UsedFontStyle>)
-> Result<FontHandle, ()> {
debug!("Creating font handle for {:s}", name);
path_from_identifier(name, &style).and_then(|file_name| {
debug!("Opening font face {:s}", file_name);
FontHandle::new_from_file(self, file_name.as_slice(), Some(&style))
})
FontHandle::new_from_file(self, name.as_slice(), style)
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.