diff options
author | Glenn Watson <gw@intuitionlibrary.com> | 2014-07-04 07:53:25 +1000 |
---|---|---|
committer | Glenn Watson <gw@intuitionlibrary.com> | 2014-07-07 14:25:21 +1000 |
commit | 12978eeb50d8f727bc020bcdd0534e80d7890c7f (patch) | |
tree | b33c8659a0faf66765fef9cc016ac766a44007f5 /src/components/gfx/platform/linux/font.rs | |
parent | e62637fee2f1c9627468dde81a68df1dd40b6bc9 (diff) | |
download | servo-12978eeb50d8f727bc020bcdd0534e80d7890c7f.tar.gz servo-12978eeb50d8f727bc020bcdd0534e80d7890c7f.zip |
Next stage of refactoring font system. This commit introduces
the font cache task, and adapts client code to use it. It also
cleans up some existing code paths.
- Fonts are only read once from disk while in use (they
are discarded if the reference count reaches zero, however).
This saves memory and prevents unnecessary reading from disk.
- It will be easier to add web font support, as all fonts
are created and managed in a single place and the entire
pipeline ensures that only one in-memory copy of font data
is required.
An overview of how the pieces fit together:
FontTemplate - A structure containing everything that
is required to create (and select) font handles. This
structure is shared among all matching font handles
(via Arc).
FontTemplateData - A platform specific structure that
contains the actual font data inside a template (this is
a byte array on Linux/Android, CTFont on Mac).
FontHandle - An opaque, platform specific handle to
a font instance. Each FontHandle contains an Arc<>
reference to the FontTemplate it was created from.
FontCache - This is a separate task, that is responsible
for loading and caching FontTemplate structures. There
is one FontCache per constellation. It is only ever accessed
via the FontContext described below.
FontContext - This is the public interface to the FontCache
and is used by the layout and render code to create font
handles. These must *not* be shared between threads. There
is typically one FontContext per thread/task.
Diffstat (limited to 'src/components/gfx/platform/linux/font.rs')
-rw-r--r-- | src/components/gfx/platform/linux/font.rs | 76 |
1 files changed, 20 insertions, 56 deletions
diff --git a/src/components/gfx/platform/linux/font.rs b/src/components/gfx/platform/linux/font.rs index 1299315ade2..3e060c0fb58 100644 --- a/src/components/gfx/platform/linux/font.rs +++ b/src/components/gfx/platform/linux/font.rs @@ -5,17 +5,18 @@ extern crate freetype; use font::{FontHandleMethods, FontMetrics, FontTableMethods}; -use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle}; +use font::{FontTableTag, FractionalPixel}; use servo_util::geometry::Au; use servo_util::geometry; use platform::font_context::FontContextHandle; use text::glyph::GlyphId; use text::util::{float_to_fixed, fixed_to_float}; use style::computed_values::font_weight; +use platform::font_template::FontTemplateData; use freetype::freetype::{FT_Get_Char_Index, FT_Get_Postscript_Name}; use freetype::freetype::{FT_Load_Glyph, FT_Set_Char_Size}; -use freetype::freetype::{FT_New_Face, FT_Get_Sfnt_Table}; +use freetype::freetype::{FT_Get_Sfnt_Table}; use freetype::freetype::{FT_New_Memory_Face, FT_Done_Face}; use freetype::freetype::{FTErrorMethods, FT_F26Dot6, FT_Face, FT_FaceRec}; use freetype::freetype::{FT_GlyphSlot, FT_Library, FT_Long, FT_ULong}; @@ -28,6 +29,8 @@ use std::mem; use std::ptr; use std::str; +use sync::Arc; + fn float_to_fixed_ft(f: f64) -> i32 { float_to_fixed(6, f) } @@ -46,15 +49,10 @@ impl FontTableMethods for FontTable { } } -pub enum FontSource { - FontSourceMem(Vec<u8>), - FontSourceFile(String) -} - pub struct FontHandle { // The font binary. This must stay valid for the lifetime of the font, // if the font is created using FT_Memory_Face. - pub source: FontSource, + pub font_data: Arc<FontTemplateData>, pub face: FT_Face, pub handle: FontContextHandle } @@ -72,14 +70,15 @@ impl Drop for FontHandle { } impl FontHandleMethods for FontHandle { - fn new_from_buffer(fctx: &FontContextHandle, - buf: Vec<u8>, - style: &SpecifiedFontStyle) + fn new_from_template(fctx: &FontContextHandle, + template: Arc<FontTemplateData>, + pt_size: Option<f64>) -> Result<FontHandle, ()> { let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } - let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size); + let bytes = &template.deref().bytes; + let face_result = create_face_from_buffer(ft_ctx, bytes.as_ptr(), bytes.len(), pt_size); // TODO: this could be more simply written as result::chain // and moving buf into the struct ctor, but cant' move out of @@ -88,7 +87,7 @@ impl FontHandleMethods for FontHandle { Ok(face) => { let handle = FontHandle { face: face, - source: FontSourceMem(buf), + font_data: template.clone(), handle: fctx.clone() }; Ok(handle) @@ -96,7 +95,7 @@ impl FontHandleMethods for FontHandle { Err(()) => Err(()) }; - fn create_face_from_buffer(lib: FT_Library, cbuf: *u8, cbuflen: uint, pt_size: f64) + fn create_face_from_buffer(lib: FT_Library, cbuf: *u8, cbuflen: uint, pt_size: Option<f64>) -> Result<FT_Face, ()> { unsafe { let mut face: FT_Face = ptr::null(); @@ -107,7 +106,11 @@ impl FontHandleMethods for FontHandle { if !result.succeeded() || face.is_null() { return Err(()); } - if FontHandle::set_char_size(face, pt_size).is_ok() { + let is_ok = match pt_size { + Some(s) => FontHandle::set_char_size(face, s).is_ok(), + None => true, + }; + if is_ok { Ok(face) } else { Err(()) @@ -115,14 +118,8 @@ impl FontHandleMethods for FontHandle { } } } - - // an identifier usable by FontContextHandle to recreate this FontHandle. - fn face_identifier(&self) -> String { - 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 get_template(&self) -> Arc<FontTemplateData> { + self.font_data.clone() } fn family_name(&self) -> String { unsafe { str::raw::from_c_str((*self.face).family_name) } @@ -265,39 +262,6 @@ impl<'a> FontHandle { } } - pub fn new_from_file(fctx: &FontContextHandle, file: &str, - maybe_style: Option<&SpecifiedFontStyle>) -> Result<FontHandle, ()> { - unsafe { - 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; - file.to_c_str().with_ref(|file_str| { - FT_New_Face(ft_ctx, file_str, - face_index, &mut face); - }); - if face.is_null() { - return Err(()); - } - - let ok = match maybe_style { - Some(style) => FontHandle::set_char_size(face, style.pt_size).is_ok(), - None => true, - }; - - if ok { - Ok(FontHandle { - source: FontSourceFile(file.to_str()), - face: face, - handle: fctx.clone() - }) - } else { - Err(()) - } - } - } - fn get_face_rec(&'a self) -> &'a FT_FaceRec { unsafe { &(*self.face) |