diff --git a/components/gfx/font_cache_task.rs b/components/gfx/font_cache_task.rs index 1b1ff6227cb..7d3541488f8 100644 --- a/components/gfx/font_cache_task.rs +++ b/components/gfx/font_cache_task.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use platform::font_list::get_available_families; +use platform::font_list::get_system_default_family; use platform::font_list::get_variations_for_family; use platform::font_list::get_last_resort_font_families; use platform::font_context::FontContextHandle; @@ -90,6 +91,16 @@ struct FontCache { resource_task: ResourceTask, } +fn add_generic_font(generic_fonts: &mut HashMap, + generic_name: &str, mapped_name: &str) { + let opt_system_default = get_system_default_family(generic_name); + let family_name = match opt_system_default { + Some(system_default) => system_default, + None => mapped_name.to_string(), + }; + generic_fonts.insert(generic_name.to_string(), family_name); +} + impl FontCache { fn run(&mut self) { loop { @@ -223,11 +234,11 @@ impl FontCacheTask { spawn(proc() { // TODO: Allow users to specify these. let mut generic_fonts = HashMap::with_capacity(5); - generic_fonts.insert("serif".to_string(), "Times New Roman".to_string()); - generic_fonts.insert("sans-serif".to_string(), "Arial".to_string()); - generic_fonts.insert("cursive".to_string(), "Apple Chancery".to_string()); - generic_fonts.insert("fantasy".to_string(), "Papyrus".to_string()); - generic_fonts.insert("monospace".to_string(), "Menlo".to_string()); + add_generic_font(&mut generic_fonts, "serif", "Times New Roman"); + add_generic_font(&mut generic_fonts, "sans-serif", "Arial"); + add_generic_font(&mut generic_fonts, "cursive", "Apple Chancery"); + add_generic_font(&mut generic_fonts, "fantasy", "Papyrus"); + add_generic_font(&mut generic_fonts, "monospace", "Menlo"); let mut cache = FontCache { port: port, diff --git a/components/gfx/platform/freetype/font.rs b/components/gfx/platform/freetype/font.rs index 7e58b850e2b..c26b6272b39 100644 --- a/components/gfx/platform/freetype/font.rs +++ b/components/gfx/platform/freetype/font.rs @@ -260,13 +260,10 @@ impl FontHandleMethods for FontHandle { impl<'a> FontHandle { fn set_char_size(face: FT_Face, pt_size: f64) -> Result<(), ()>{ - let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6; - let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6; - let h_dpi = 72; - let v_dpi = 72; + let char_width = float_to_fixed_ft((0.5f64 + pt_size).floor()) as FT_F26Dot6; unsafe { - let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi); + let result = FT_Set_Char_Size(face, char_width, 0, 0, 0); if result.succeeded() { Ok(()) } else { Err(()) } } } diff --git a/components/gfx/platform/freetype/font_list.rs b/components/gfx/platform/freetype/font_list.rs index 87ce446381d..9e412bad6b0 100644 --- a/components/gfx/platform/freetype/font_list.rs +++ b/components/gfx/platform/freetype/font_list.rs @@ -9,8 +9,12 @@ extern crate fontconfig; use fontconfig::fontconfig::{FcChar8, FcResultMatch, FcSetSystem}; use fontconfig::fontconfig::{ - FcConfigGetCurrent, FcConfigGetFonts, FcPatternGetString, + FcConfigGetCurrent, FcConfigGetFonts, + FcConfigSubstitute, FcDefaultSubstitute, + FcFontMatch, + FcNameParse, FcPatternGetString, FcPatternDestroy, FcFontSetDestroy, + FcMatchPattern, FcPatternCreate, FcPatternAddString, FcFontSetList, FcObjectSetCreate, FcObjectSetDestroy, FcObjectSetAdd, FcPatternGetInteger @@ -21,6 +25,10 @@ use libc::c_int; use std::ptr; use std::string; +static FC_FAMILY: &'static [u8] = b"family\0"; +static FC_FILE: &'static [u8] = b"file\0"; +static FC_INDEX: &'static [u8] = b"index\0"; + pub fn get_available_families(callback: |String|) { unsafe { let config = FcConfigGetCurrent(); @@ -29,9 +37,7 @@ pub fn get_available_families(callback: |String|) { let font = (*fontSet).fonts.offset(i); let mut family: *mut FcChar8 = ptr::mut_null(); let mut v: c_int = 0; - let mut FC_FAMILY_C = "family".to_c_str(); - let FC_FAMILY = FC_FAMILY_C.as_mut_ptr(); - while FcPatternGetString(*font, FC_FAMILY, v, &mut family) == FcResultMatch { + while FcPatternGetString(*font, FC_FAMILY.as_ptr() as *mut i8, v, &mut family) == FcResultMatch { let family_name = string::raw::from_buf(family as *const i8 as *const u8); callback(family_name); v += 1; @@ -48,22 +54,16 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { let font_set_array_ptr = &mut font_set; let pattern = FcPatternCreate(); assert!(pattern.is_not_null()); - let mut FC_FAMILY_C = "family".to_c_str(); - let FC_FAMILY = FC_FAMILY_C.as_mut_ptr(); let mut family_name_c = family_name.to_c_str(); let family_name = family_name_c.as_mut_ptr(); - let ok = FcPatternAddString(pattern, FC_FAMILY, family_name as *mut FcChar8); + let ok = FcPatternAddString(pattern, FC_FAMILY.as_ptr() as *mut i8, family_name as *mut FcChar8); assert!(ok != 0); let object_set = FcObjectSetCreate(); assert!(object_set.is_not_null()); - let mut FC_FILE_C = "file".to_c_str(); - let FC_FILE = FC_FILE_C.as_mut_ptr(); - FcObjectSetAdd(object_set, FC_FILE); - let mut FC_INDEX_C = "index".to_c_str(); - let FC_INDEX = FC_INDEX_C.as_mut_ptr(); - FcObjectSetAdd(object_set, FC_INDEX); + FcObjectSetAdd(object_set, FC_FILE.as_ptr() as *mut i8); + FcObjectSetAdd(object_set, FC_INDEX.as_ptr() as *mut i8); let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set); @@ -71,18 +71,14 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { for i in range(0, (*matches).nfont as int) { let font = (*matches).fonts.offset(i); - let mut FC_FILE_C = "file".to_c_str(); - let FC_FILE = FC_FILE_C.as_mut_ptr(); let mut file: *mut FcChar8 = ptr::mut_null(); - let file = if FcPatternGetString(*font, FC_FILE, 0, &mut file) == FcResultMatch { + let file = if FcPatternGetString(*font, FC_FILE.as_ptr() as *mut i8, 0, &mut file) == FcResultMatch { string::raw::from_buf(file as *const i8 as *const u8) } else { fail!(); }; - let mut FC_INDEX_C = "index".to_c_str(); - let FC_INDEX = FC_INDEX_C.as_mut_ptr(); let mut index: libc::c_int = 0; - let index = if FcPatternGetInteger(*font, FC_INDEX, 0, &mut index) == FcResultMatch { + let index = if FcPatternGetInteger(*font, FC_INDEX.as_ptr() as *mut i8, 0, &mut index) == FcResultMatch { index } else { fail!(); @@ -100,6 +96,34 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { } } +pub fn get_system_default_family(generic_name: &str) -> Option { + let mut generic_name_c = generic_name.to_c_str(); + let generic_name_ptr = generic_name_c.as_mut_ptr(); + + unsafe { + let pattern = FcNameParse(generic_name_ptr as *mut FcChar8); + + FcConfigSubstitute(ptr::mut_null(), pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + let mut result = 0; + let family_match = FcFontMatch(ptr::mut_null(), pattern, &mut result); + + let family_name = if result == FcResultMatch { + let mut match_string: *mut FcChar8 = ptr::mut_null(); + FcPatternGetString(family_match, FC_FAMILY.as_ptr() as *mut i8, 0, &mut match_string); + let result = string::raw::from_buf(match_string as *const i8 as *const u8); + FcPatternDestroy(family_match); + Some(result) + } else { + None + }; + + FcPatternDestroy(pattern); + family_name + } +} + #[cfg(target_os="linux")] pub fn get_last_resort_font_families() -> Vec { vec!( diff --git a/components/gfx/platform/macos/font_list.rs b/components/gfx/platform/macos/font_list.rs index 4ec319ec6b2..74e22d0feb9 100644 --- a/components/gfx/platform/macos/font_list.rs +++ b/components/gfx/platform/macos/font_list.rs @@ -32,6 +32,10 @@ pub fn get_variations_for_family(family_name: &str, callback: |String|) { } } +pub fn get_system_default_family(_generic_name: &str) -> Option { + None +} + pub fn get_last_resort_font_families() -> Vec { vec!("Arial Unicode MS".to_string(), "Arial".to_string()) }