mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
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:
parent
4aa9bbd2ab
commit
357905c202
7 changed files with 50 additions and 19 deletions
|
@ -4,11 +4,12 @@ use gfx::geometry::*;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use image::base::Image;
|
use image::base::Image;
|
||||||
use render_task::RenderContext;
|
use render_task::RenderContext;
|
||||||
|
use servo_text::text_run;
|
||||||
|
|
||||||
use std::arc::ARC;
|
use std::arc::ARC;
|
||||||
use clone_arc = std::arc::clone;
|
use clone_arc = std::arc::clone;
|
||||||
use dvec::DVec;
|
use dvec::DVec;
|
||||||
use text::text_run::TextRun;
|
use text::text_run::SendableTextRun;
|
||||||
|
|
||||||
pub use layout::display_list_builder::DisplayListBuilder;
|
pub use layout::display_list_builder::DisplayListBuilder;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ pub enum DisplayItemData {
|
||||||
// TODO: need to provide spacing data for text run.
|
// TODO: need to provide spacing data for text run.
|
||||||
// (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing')
|
// (i.e, to support rendering of CSS 'word-spacing' and 'letter-spacing')
|
||||||
// TODO: don't copy text runs, ever.
|
// TODO: don't copy text runs, ever.
|
||||||
TextData(~TextRun, uint, uint),
|
TextData(~SendableTextRun, uint, uint),
|
||||||
ImageData(ARC<~image::base::Image>),
|
ImageData(ARC<~image::base::Image>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +38,10 @@ fn draw_SolidColor(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
|
|
||||||
fn draw_Text(self: &DisplayItem, ctx: &RenderContext) {
|
fn draw_Text(self: &DisplayItem, ctx: &RenderContext) {
|
||||||
match self.data {
|
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
|
_ => 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 {
|
DisplayItem {
|
||||||
draw: |self, ctx| draw_Text(self, ctx),
|
draw: |self, ctx| draw_Text(self, ctx),
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
|
|
|
@ -172,8 +172,7 @@ pub fn draw_text(ctx: &RenderContext, bounds: Rect<au>, run: &TextRun, offset: u
|
||||||
AzReleaseColorPattern};
|
AzReleaseColorPattern};
|
||||||
use azure::cairo::bindgen::cairo_scaled_font_destroy;
|
use azure::cairo::bindgen::cairo_scaled_font_destroy;
|
||||||
|
|
||||||
// FIXME: font should be accessible from TextRun
|
let font = run.font;
|
||||||
let font = ctx.font_cache.get_test_font();
|
|
||||||
|
|
||||||
let nfont: AzNativeFont = {
|
let nfont: AzNativeFont = {
|
||||||
mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,
|
mType: AZ_NATIVE_FONT_CAIRO_FONT_FACE,
|
||||||
|
|
|
@ -20,6 +20,7 @@ use layout::context::LayoutContext;
|
||||||
use layout::debug::BoxedDebugMethods;
|
use layout::debug::BoxedDebugMethods;
|
||||||
use layout::flow::FlowContext;
|
use layout::flow::FlowContext;
|
||||||
use layout::text::TextBoxData;
|
use layout::text::TextBoxData;
|
||||||
|
use servo_text::text_run;
|
||||||
use servo_text::text_run::TextRun;
|
use servo_text::text_run::TextRun;
|
||||||
use std::net::url::Url;
|
use std::net::url::Url;
|
||||||
use task::spawn;
|
use task::spawn;
|
||||||
|
@ -331,7 +332,7 @@ impl RenderBox : RenderBoxMethods {
|
||||||
* `origin` - Total offset from display list root flow to this box's owning flow
|
* `origin` - Total offset from display list root flow to this box's owning flow
|
||||||
* `list` - List to which items should be appended
|
* `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) {
|
offset: &Point2D<au>, list: &dl::DisplayList) {
|
||||||
if !self.d().position.intersects(dirty) {
|
if !self.d().position.intersects(dirty) {
|
||||||
return;
|
return;
|
||||||
|
@ -345,7 +346,7 @@ impl RenderBox : RenderBoxMethods {
|
||||||
match self {
|
match self {
|
||||||
UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
|
UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
|
||||||
TextBox(_,d) => {
|
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
|
// TODO: items for background, border, outline
|
||||||
GenericBox(_) => {
|
GenericBox(_) => {
|
||||||
|
|
|
@ -161,7 +161,7 @@ impl TextRunScanner {
|
||||||
let compression = CompressWhitespaceNewline;
|
let compression = CompressWhitespaceNewline;
|
||||||
let transformed_text = transform_text(text, compression);
|
let transformed_text = transform_text(text, compression);
|
||||||
// TODO(Issue #116): use actual font for corresponding DOM node to create text run.
|
// 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());
|
let box_guts = TextBoxData(run, 0, run.text.len());
|
||||||
debug!("TextRunScanner: pushing single text box when start=%u,end=%u",
|
debug!("TextRunScanner: pushing single text box when start=%u,end=%u",
|
||||||
self.clump_start, self.clump_end);
|
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.
|
// 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());
|
let box_guts = TextBoxData(run, 0, run.text.len());
|
||||||
debug!("TextRunScanner: pushing box(es) when start=%u,end=%u",
|
debug!("TextRunScanner: pushing box(es) when start=%u,end=%u",
|
||||||
self.clump_start, self.clump_end);
|
self.clump_start, self.clump_end);
|
||||||
|
|
|
@ -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 {
|
struct FontMetrics {
|
||||||
underline_size: au,
|
underline_size: au,
|
||||||
underline_offset: au,
|
underline_offset: au,
|
||||||
|
|
|
@ -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
|
Calculate the layout metrics associated with a some given text
|
||||||
when rendered in a specific font.
|
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);
|
debug!("shaping text '%s'", run.text);
|
||||||
|
|
||||||
// TODO: harfbuzz fonts and faces should be cached on the Font object.
|
// 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)
|
// 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,
|
hb_blob_create(buf as *c_char,
|
||||||
len as c_uint,
|
len as c_uint,
|
||||||
HB_MEMORY_MODE_READONLY,
|
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());
|
hb_font_funcs_set_glyph_h_advance_func(funcs, glyph_h_advance_func, null(), null());
|
||||||
|
|
||||||
unsafe {
|
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());
|
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,
|
glyph: *mut hb_codepoint_t,
|
||||||
_user_data: *c_void) -> hb_bool_t unsafe {
|
_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();
|
assert font.is_not_null();
|
||||||
|
|
||||||
return match (*font).glyph_index(unicode as char) {
|
return match (*font).glyph_index(unicode as char) {
|
||||||
Some(g) => { *glyph = g as hb_codepoint_t; true },
|
Some(g) => { *glyph = g as hb_codepoint_t; true },
|
||||||
None => false
|
None => false
|
||||||
|
@ -153,8 +152,9 @@ extern fn glyph_h_advance_func(_font: *hb_font_t,
|
||||||
font_data: *c_void,
|
font_data: *c_void,
|
||||||
glyph: hb_codepoint_t,
|
glyph: hb_codepoint_t,
|
||||||
_user_data: *c_void) -> hb_position_t unsafe {
|
_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();
|
assert font.is_not_null();
|
||||||
|
debug!("font_data = %?", font_data);
|
||||||
|
|
||||||
let advance = (*font).glyph_h_advance(glyph as GlyphIndex);
|
let advance = (*font).glyph_h_advance(glyph as GlyphIndex);
|
||||||
float_to_fixed_hb(advance)
|
float_to_fixed_hb(advance)
|
||||||
|
|
|
@ -15,9 +15,36 @@ use std::arc;
|
||||||
|
|
||||||
pub struct TextRun {
|
pub struct TextRun {
|
||||||
text: ~str,
|
text: ~str,
|
||||||
|
font: @Font,
|
||||||
priv glyphs: GlyphStore,
|
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 {
|
trait TextRunMethods {
|
||||||
pure fn glyphs(&self) -> &self/GlyphStore;
|
pure fn glyphs(&self) -> &self/GlyphStore;
|
||||||
pure fn iter_indivisible_pieces_for_range(&self, offset: uint, length: uint, f: fn(uint, uint) -> bool);
|
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 glyph_store = GlyphStore(text.len());
|
||||||
let run = TextRun {
|
let run = TextRun {
|
||||||
text: text,
|
text: text,
|
||||||
|
font: font,
|
||||||
glyphs: glyph_store,
|
glyphs: glyph_store,
|
||||||
};
|
};
|
||||||
|
|
||||||
shape_textrun(font, &run);
|
shape_textrun(&run);
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue