From 905ad4a88ea2e92a22c592e8f5a51778c4ca7f5f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 7 Jan 2013 14:01:31 -0800 Subject: [PATCH] Implement load_variations_for_family for FontConfig --- src/servo-gfx/fontconfig/font_list.rs | 67 +++++++++++++++++++++++++-- src/servo-gfx/freetype_impl/font.rs | 19 ++++++++ 2 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/servo-gfx/fontconfig/font_list.rs b/src/servo-gfx/fontconfig/font_list.rs index d0df8c854af..619ad0ba7f3 100644 --- a/src/servo-gfx/fontconfig/font_list.rs +++ b/src/servo-gfx/fontconfig/font_list.rs @@ -7,6 +7,7 @@ use ft = freetype; use gfx_font::FontHandle; use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap}; use freetype_impl::font_context::FreeTypeFontContextHandle; +use freetype_impl::font::FreeTypeFontHandle; use self::fontconfig::fontconfig::{FcConfig, FcFontSet, FcChar8, FcResultMatch, FcSetSystem, FcPattern, FcResultNoMatch, FcMatchPattern}; @@ -15,7 +16,9 @@ use self::fontconfig::fontconfig::bindgen::{ FcInitReinitialize, FcPatternDestroy, FcPatternReference, FcFontSetDestroy, FcCharSetDestroy, FcConfigSubstitute, FcDefaultSubstitute, FcPatternCreate, FcPatternAddString, - FcFontMatch, + FcFontMatch, FcFontSetCreate, FcFontSetList, FcPatternPrint, + FcObjectSetCreate, FcObjectSetDestroy, FcObjectSetAdd, + FcPatternGetInteger }; use core::dvec::DVec; @@ -55,8 +58,66 @@ pub impl FontconfigFontListHandle { return family_map; } - fn load_variations_for_family(_family: @FontFamily) { - fail + fn load_variations_for_family(family: @FontFamily) { + debug!("getting variations for %?", family); + let config = FcConfigGetCurrent(); + let font_set = FcConfigGetFonts(config, FcSetSystem); + let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set); + unsafe { + do str::as_c_str("family") |FC_FAMILY| { + do str::as_c_str(family.family_name) |family_name| { + let pattern = FcPatternCreate(); + assert pattern.is_not_null(); + let family_name = family_name as *FcChar8; + let ok = FcPatternAddString(pattern, FC_FAMILY, family_name); + assert ok != 0; + + let object_set = FcObjectSetCreate(); + assert object_set.is_not_null(); + + str::as_c_str("file", |FC_FILE| FcObjectSetAdd(object_set, FC_FILE) ); + str::as_c_str("index", |FC_INDEX| FcObjectSetAdd(object_set, FC_INDEX) ); + + let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set); + + debug!("found %? variations", (*matches).nfont); + + for uint::range(0, (*matches).nfont as uint) |i| { + let font = (*matches).fonts.offset(i); + let file = do str::as_c_str("file") |FC_FILE| { + let file: *FcChar8 = ptr::null(); + if FcPatternGetString(*font, FC_FILE, 0, &file) == FcResultMatch { + str::raw::from_c_str(file as *libc::c_char) + } else { + fail; + } + }; + let index = do str::as_c_str("index") |FC_INDEX| { + let index: libc::c_int = 0; + if FcPatternGetInteger(*font, FC_INDEX, 0, &index) == FcResultMatch { + index + } else { + fail; + } + }; + + debug!("variation file: %?", file); + debug!("variation index: %?", index); + + let font_handle = FreeTypeFontHandle::new_from_file_unstyled(&self.fctx, file); + let font_handle = font_handle.unwrap(); + + debug!("Creating new FontEntry for face: %s", font_handle.face_name()); + let entry = @FontEntry::new(family, move font_handle); + family.entries.push(entry); + } + + FcFontSetDestroy(matches); + FcPatternDestroy(pattern); + FcObjectSetDestroy(object_set); + } + } + } } } diff --git a/src/servo-gfx/freetype_impl/font.rs b/src/servo-gfx/freetype_impl/font.rs index c907557cfe9..00f8555f24b 100644 --- a/src/servo-gfx/freetype_impl/font.rs +++ b/src/servo-gfx/freetype_impl/font.rs @@ -122,6 +122,25 @@ pub impl FreeTypeFontHandle { Err(()) } } + + static pub fn new_from_file_unstyled(fctx: &FreeTypeFontContextHandle, file: ~str) + -> Result { + let ft_ctx: FT_Library = fctx.ctx.ctx; + if ft_ctx.is_null() { return Err(()); } + + let mut face: FT_Face = ptr::null(); + let face_index = 0 as FT_Long; + do str::as_c_str(file) |file_str| { + FT_New_Face(ft_ctx, file_str, + face_index, ptr::to_unsafe_ptr(&face)); + } + if face.is_null() { + return Err(()); + } + + Ok(FreeTypeFontHandle { buf: ~[], face: face }) + } + static pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { let ft_ctx: FT_Library = fctx.ctx.ctx;