mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Add some RAII and black magic to let harfbuzz determine font table blob lifetimes.
This commit is contained in:
parent
b14505e44d
commit
c74abcaa5c
3 changed files with 79 additions and 29 deletions
|
@ -35,7 +35,7 @@ pub trait FontHandleMethods {
|
||||||
fn glyph_index(codepoint: char) -> Option<GlyphIndex>;
|
fn glyph_index(codepoint: char) -> Option<GlyphIndex>;
|
||||||
fn glyph_h_advance(GlyphIndex) -> Option<FractionalPixel>;
|
fn glyph_h_advance(GlyphIndex) -> Option<FractionalPixel>;
|
||||||
fn get_metrics() -> FontMetrics;
|
fn get_metrics() -> FontMetrics;
|
||||||
fn get_table_for_tag(FontTableTag) -> Option<~[u8]>;
|
fn get_table_for_tag(FontTableTag) -> Option<FontTable>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(Issue #163): this is a workaround for static methods and
|
// TODO(Issue #163): this is a workaround for static methods and
|
||||||
|
@ -74,6 +74,16 @@ impl FontTableTag : FontTableTagConversions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub type FontTable/& = quartz::font::QuartzFontTable;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub type FontTable/& = freetype::font::FreeTypeFontTable;
|
||||||
|
|
||||||
|
trait FontTableMethods {
|
||||||
|
fn with_buffer(fn&(*u8, uint));
|
||||||
|
}
|
||||||
|
|
||||||
struct FontMetrics {
|
struct FontMetrics {
|
||||||
underline_size: Au,
|
underline_size: Au,
|
||||||
underline_offset: Au,
|
underline_offset: Au,
|
||||||
|
@ -311,7 +321,7 @@ impl Font {
|
||||||
shaper
|
shaper
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_table_for_tag(tag: FontTableTag) -> Option<~[u8]> {
|
fn get_table_for_tag(tag: FontTableTag) -> Option<FontTable> {
|
||||||
let result = self.handle.get_table_for_tag(tag);
|
let result = self.handle.get_table_for_tag(tag);
|
||||||
let status = if result.is_some() { "Found" } else { "Didn't find" };
|
let status = if result.is_some() { "Found" } else { "Didn't find" };
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,35 @@ extern mod core_foundation;
|
||||||
extern mod core_graphics;
|
extern mod core_graphics;
|
||||||
extern mod core_text;
|
extern mod core_text;
|
||||||
|
|
||||||
|
use cf = core_foundation;
|
||||||
|
use cf::base::{
|
||||||
|
CFIndex,
|
||||||
|
CFRelease,
|
||||||
|
CFTypeOps,
|
||||||
|
CFTypeRef,
|
||||||
|
};
|
||||||
|
use cf::data::{CFData, CFDataRef};
|
||||||
|
use cf::string::UniChar;
|
||||||
|
use cg = core_graphics;
|
||||||
|
|
||||||
|
use cg::base::{CGFloat, CGAffineTransform};
|
||||||
|
use cg::data_provider::{CGDataProviderRef, CGDataProvider};
|
||||||
|
use cg::font::{CGFontCreateWithDataProvider, CGFontRef, CGFontRelease, CGGlyph};
|
||||||
|
use cg::geometry::CGRect;
|
||||||
|
|
||||||
|
use ct = core_text;
|
||||||
|
use ct::font::CTFont;
|
||||||
|
use ct::font_descriptor::{kCTFontDefaultOrientation, CTFontSymbolicTraits};
|
||||||
|
use ct::font_descriptor::{SymbolicTraitAccessors};
|
||||||
|
|
||||||
use font_context::QuartzFontContextHandle;
|
use font_context::QuartzFontContextHandle;
|
||||||
use geometry::Au;
|
use geometry::Au;
|
||||||
use gfx_font::{
|
use gfx_font::{
|
||||||
CSSFontWeight,
|
CSSFontWeight,
|
||||||
FontHandleMethods,
|
FontHandleMethods,
|
||||||
FontMetrics,
|
FontMetrics,
|
||||||
|
FontTable,
|
||||||
|
FontTableMethods,
|
||||||
FontTableTag,
|
FontTableTag,
|
||||||
FontWeight100,
|
FontWeight100,
|
||||||
FontWeight200,
|
FontWeight200,
|
||||||
|
@ -23,24 +46,25 @@ use gfx_font::{
|
||||||
};
|
};
|
||||||
use text::glyph::GlyphIndex;
|
use text::glyph::GlyphIndex;
|
||||||
|
|
||||||
use cf = core_foundation;
|
|
||||||
use cf::base::{
|
|
||||||
CFIndex,
|
|
||||||
CFRelease,
|
|
||||||
CFTypeRef
|
|
||||||
};
|
|
||||||
use cf::data::CFData;
|
|
||||||
use cf::string::UniChar;
|
|
||||||
use cg = core_graphics;
|
|
||||||
use cg::base::{CGFloat, CGAffineTransform};
|
|
||||||
use cg::data_provider::{CGDataProviderRef, CGDataProvider};
|
|
||||||
use cg::font::{CGFontCreateWithDataProvider, CGFontRef, CGFontRelease, CGGlyph};
|
|
||||||
use cg::geometry::CGRect;
|
|
||||||
use core::libc::size_t;
|
use core::libc::size_t;
|
||||||
use ct = core_text;
|
|
||||||
use ct::font::CTFont;
|
struct QuartzFontTable {
|
||||||
use ct::font_descriptor::{kCTFontDefaultOrientation, CTFontSymbolicTraits};
|
data: CFData,
|
||||||
use ct::font_descriptor::{SymbolicTraitAccessors};
|
|
||||||
|
drop { }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl QuartzFontTable {
|
||||||
|
static fn wrap(data: CFData) -> QuartzFontTable {
|
||||||
|
QuartzFontTable { data: move data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub impl QuartzFontTable : FontTableMethods {
|
||||||
|
fn with_buffer(blk: fn&(*u8, uint)) {
|
||||||
|
blk(self.data.bytes(), self.data.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct QuartzFontHandle {
|
pub struct QuartzFontHandle {
|
||||||
priv mut cgfont: Option<CGFontRef>,
|
priv mut cgfont: Option<CGFontRef>,
|
||||||
|
@ -182,10 +206,10 @@ pub impl QuartzFontHandle : FontHandleMethods {
|
||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_table_for_tag(tag: FontTableTag) -> Option<~[u8]> {
|
fn get_table_for_tag(tag: FontTableTag) -> Option<FontTable> {
|
||||||
let result = self.ctfont.get_font_table(tag);
|
let result : Option<CFData> = self.ctfont.get_font_table(tag);
|
||||||
return option::chain(move result, |data| {
|
return option::chain(move result, |data| {
|
||||||
Some(data.copy_to_buf())
|
Some(QuartzFontTable::wrap(move data))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use au::Au;
|
||||||
|
|
||||||
use font::{
|
use font::{
|
||||||
Font,
|
Font,
|
||||||
|
FontTable,
|
||||||
FontTableTag,
|
FontTableTag,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,16 +192,31 @@ extern fn get_font_table_func(_face: *hb_face_t, tag: hb_tag_t, user_data: *c_vo
|
||||||
let font: *Font = user_data as *Font;
|
let font: *Font = user_data as *Font;
|
||||||
assert font.is_not_null();
|
assert font.is_not_null();
|
||||||
|
|
||||||
// TODO(Issue #197): reuse font table data, which will change return type here.
|
// TODO(Issue #197): reuse font table data, which will change the unsound trickery here.
|
||||||
// it will also require us to provide deletion callbacks to hb_blob_create, so
|
|
||||||
// that refcounts of shared blobs can be managed.
|
|
||||||
match (*font).get_table_for_tag(tag as FontTableTag) {
|
match (*font).get_table_for_tag(tag as FontTableTag) {
|
||||||
None => return ptr::null(),
|
None => return ptr::null(),
|
||||||
Some(table_buffer) => {
|
Some(ref font_table) => {
|
||||||
let blob: *hb_blob_t = vec::as_imm_buf(table_buffer, |buf: *u8, len: uint| {
|
let skinny_font_table = ~font_table;
|
||||||
hb_blob_create(buf as *c_char, len as c_uint, HB_MEMORY_MODE_READONLY, null(), null())
|
let skinny_font_table_ptr = ptr::to_unsafe_ptr(skinny_font_table);
|
||||||
|
let mut blob: *hb_blob_t = ptr::null();
|
||||||
|
(*skinny_font_table_ptr).with_buffer(|buf: *u8, len: uint| {
|
||||||
|
blob = hb_blob_create(buf as *c_char,
|
||||||
|
len as c_uint,
|
||||||
|
HB_MEMORY_MODE_READONLY,
|
||||||
|
cast::transmute(skinny_font_table_ptr), // private context for below.
|
||||||
|
destroy_blob_func); // HarfBuzz calls this when blob not needed.
|
||||||
});
|
});
|
||||||
|
assert blob.is_not_null();
|
||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Issue #197): reuse font table data, which will change the unsound trickery here.
|
||||||
|
// In particular, we'll need to cast to a boxed, rather than owned, FontTable.
|
||||||
|
|
||||||
|
// even better, should cache the harfbuzz blobs directly instead of recreating a lot.
|
||||||
|
extern fn destroy_blob_func(user_data: *c_void) unsafe {
|
||||||
|
// this will cause drop to run.
|
||||||
|
let _wrapper : &~FontTable = cast::transmute(user_data);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue