aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/gfx/platform/linux/font.rs
diff options
context:
space:
mode:
authorGlenn Watson <gw@intuitionlibrary.com>2014-07-04 07:53:25 +1000
committerGlenn Watson <gw@intuitionlibrary.com>2014-07-07 14:25:21 +1000
commit12978eeb50d8f727bc020bcdd0534e80d7890c7f (patch)
treeb33c8659a0faf66765fef9cc016ac766a44007f5 /src/components/gfx/platform/linux/font.rs
parente62637fee2f1c9627468dde81a68df1dd40b6bc9 (diff)
downloadservo-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.rs76
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)