Store text run's font on the TextRun object; write a dummy serialize/deserialize method so textruns can still be copied into/out of display list.

This commit is contained in:
Brian J. Burg 2012-10-15 16:42:37 -07:00
parent 4aa9bbd2ab
commit 357905c202
7 changed files with 50 additions and 19 deletions

View file

@ -4,11 +4,12 @@ use gfx::geometry::*;
use geom::rect::Rect;
use image::base::Image;
use render_task::RenderContext;
use servo_text::text_run;
use std::arc::ARC;
use clone_arc = std::arc::clone;
use dvec::DVec;
use text::text_run::TextRun;
use text::text_run::SendableTextRun;
pub use layout::display_list_builder::DisplayListBuilder;
@ -24,7 +25,7 @@ pub enum DisplayItemData {
// TODO: need to provide spacing data for text run.
// (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing')
// TODO: don't copy text runs, ever.
TextData(~TextRun, uint, uint),
TextData(~SendableTextRun, uint, uint),
ImageData(ARC<~image::base::Image>),
}
@ -37,7 +38,10 @@ fn draw_SolidColor(self: &DisplayItem, ctx: &RenderContext) {
fn draw_Text(self: &DisplayItem, ctx: &RenderContext) {
match self.data {
TextData(~run, offset, len) => draw_text(ctx, self.bounds, &run, offset, len),
TextData(run, offset, len) => {
let new_run = text_run::deserialize(ctx.font_cache, run);
draw_text(ctx, self.bounds, new_run, offset, len)
},
_ => fail
}
}
@ -57,7 +61,7 @@ pub fn SolidColor(bounds: Rect<au>, r: u8, g: u8, b: u8) -> DisplayItem {
}
}
pub fn Text(bounds: Rect<au>, run: ~TextRun, offset: uint, length: uint) -> DisplayItem {
pub fn Text(bounds: Rect<au>, run: ~SendableTextRun, offset: uint, length: uint) -> DisplayItem {
DisplayItem {
draw: |self, ctx| draw_Text(self, ctx),
bounds: bounds,

View file

@ -172,8 +172,7 @@ pub fn draw_text(ctx: &RenderContext, bounds: Rect<au>, run: &TextRun, offset: u
AzReleaseColorPattern};
use azure::cairo::bindgen::cairo_scaled_font_destroy;
// FIXME: font should be accessible from TextRun
let font = ctx.font_cache.get_test_font();
let font = run.font;
let nfont: AzNativeFont = {
mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,

View file

@ -20,6 +20,7 @@ use layout::context::LayoutContext;
use layout::debug::BoxedDebugMethods;
use layout::flow::FlowContext;
use layout::text::TextBoxData;
use servo_text::text_run;
use servo_text::text_run::TextRun;
use std::net::url::Url;
use task::spawn;
@ -331,7 +332,7 @@ impl RenderBox : RenderBoxMethods {
* `origin` - Total offset from display list root flow to this box's owning flow
* `list` - List to which items should be appended
*/
fn build_display_list(_builder: &dl::DisplayListBuilder, dirty: &Rect<au>,
fn build_display_list(builder: &dl::DisplayListBuilder, dirty: &Rect<au>,
offset: &Point2D<au>, list: &dl::DisplayList) {
if !self.d().position.intersects(dirty) {
return;
@ -345,7 +346,7 @@ impl RenderBox : RenderBoxMethods {
match self {
UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
TextBox(_,d) => {
list.push(~dl::Text(bounds, ~(copy *d.run), d.offset, d.length))
list.push(~dl::Text(bounds, text_run::serialize(builder.ctx.font_cache, d.run), d.offset, d.length))
},
// TODO: items for background, border, outline
GenericBox(_) => {

View file

@ -161,7 +161,7 @@ impl TextRunScanner {
let compression = CompressWhitespaceNewline;
let transformed_text = transform_text(text, compression);
// TODO(Issue #116): use actual font for corresponding DOM node to create text run.
let run = @TextRun(&*ctx.font_cache.get_test_font(), move transformed_text);
let run = @TextRun(ctx.font_cache.get_test_font(), move transformed_text);
let box_guts = TextBoxData(run, 0, run.text.len());
debug!("TextRunScanner: pushing single text box when start=%u,end=%u",
self.clump_start, self.clump_end);
@ -214,7 +214,7 @@ impl TextRunScanner {
}
// TODO(Issue #116): use actual font for corresponding DOM node to create text run.
let run = @TextRun(&*ctx.font_cache.get_test_font(), move run_str);
let run = @TextRun(ctx.font_cache.get_test_font(), move run_str);
let box_guts = TextBoxData(run, 0, run.text.len());
debug!("TextRunScanner: pushing box(es) when start=%u,end=%u",
self.clump_start, self.clump_end);

View file

@ -105,7 +105,6 @@ fn Font(lib: @FontCache, fontbuf: @~[u8], native_font: NativeFont) -> Font {
}
}
// Most of these metrics are in terms of em. Use em_size to convert to au.
struct FontMetrics {
underline_size: au,
underline_offset: au,

View file

@ -52,12 +52,12 @@ fn fixed_to_rounded_int_hb(f: hb_position_t) -> int {
Calculate the layout metrics associated with a some given text
when rendered in a specific font.
*/
pub fn shape_textrun(font: &Font, run: &TextRun) {
pub fn shape_textrun(run: &TextRun) {
debug!("shaping text '%s'", run.text);
// TODO: harfbuzz fonts and faces should be cached on the Font object.
// TODO: font tables should be stored in Font object and cached by FontCache (Issue #92)
let face_blob: *hb_blob_t = vec::as_imm_buf(*(*font).fontbuf, |buf: *u8, len: uint| {
let face_blob: *hb_blob_t = vec::as_imm_buf(*(run.font).fontbuf, |buf: *u8, len: uint| {
hb_blob_create(buf as *c_char,
len as c_uint,
HB_MEMORY_MODE_READONLY,
@ -79,7 +79,7 @@ pub fn shape_textrun(font: &Font, run: &TextRun) {
hb_font_funcs_set_glyph_h_advance_func(funcs, glyph_h_advance_func, null(), null());
unsafe {
let font_data: *c_void = cast::transmute(font);
let font_data: *c_void = core::ptr::addr_of(run.font) as *c_void;
hb_font_set_funcs(hb_font, funcs, font_data, null());
};
@ -140,9 +140,8 @@ extern fn glyph_func(_font: *hb_font_t,
glyph: *mut hb_codepoint_t,
_user_data: *c_void) -> hb_bool_t unsafe {
let font: *Font = cast::transmute(font_data);
let font: *Font = font_data as *Font;
assert font.is_not_null();
return match (*font).glyph_index(unicode as char) {
Some(g) => { *glyph = g as hb_codepoint_t; true },
None => false
@ -153,8 +152,9 @@ extern fn glyph_h_advance_func(_font: *hb_font_t,
font_data: *c_void,
glyph: hb_codepoint_t,
_user_data: *c_void) -> hb_position_t unsafe {
let font: *Font = cast::transmute(font_data);
let font: *Font = font_data as *Font;
assert font.is_not_null();
debug!("font_data = %?", font_data);
let advance = (*font).glyph_h_advance(glyph as GlyphIndex);
float_to_fixed_hb(advance)

View file

@ -15,9 +15,36 @@ use std::arc;
pub struct TextRun {
text: ~str,
font: @Font,
priv glyphs: GlyphStore,
}
// This is a hack until TextRuns are normally sendable, or
// we instead use ARC<TextRun> everywhere.
pub struct SendableTextRun {
text: ~str,
font_descriptor: (),
priv glyphs: GlyphStore,
}
pub fn serialize(_cache: @FontCache, run: &TextRun) -> ~SendableTextRun {
~SendableTextRun {
text: copy run.text,
// TODO: actually serialize a font descriptor thingy
font_descriptor: (),
glyphs: copy run.glyphs,
}
}
pub fn deserialize(cache: @FontCache, run: &SendableTextRun) -> @TextRun {
@TextRun {
text: copy run.text,
// TODO: actually deserialize a font descriptor thingy
font: cache.get_test_font(),
glyphs: copy run.glyphs
}
}
trait TextRunMethods {
pure fn glyphs(&self) -> &self/GlyphStore;
pure fn iter_indivisible_pieces_for_range(&self, offset: uint, length: uint, f: fn(uint, uint) -> bool);
@ -128,14 +155,15 @@ impl TextRun : TextRunMethods {
}
}
fn TextRun(font: &Font, text: ~str) -> TextRun {
fn TextRun(font: @Font, text: ~str) -> TextRun {
let glyph_store = GlyphStore(text.len());
let run = TextRun {
text: text,
font: font,
glyphs: glyph_store,
};
shape_textrun(font, &run);
shape_textrun(&run);
return run;
}