diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2013-12-09 19:39:40 -0800 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2013-12-09 19:40:08 -0800 |
commit | 30bbaa49b700140574c5848955abba4b8d2dc48c (patch) | |
tree | 0f1ef97233c8509d2eeb43e00b8f968544376d88 | |
parent | e8ffac13d7e0ebc0701b87b774491b2b1b895607 (diff) | |
download | servo-30bbaa49b700140574c5848955abba4b8d2dc48c.tar.gz servo-30bbaa49b700140574c5848955abba4b8d2dc48c.zip |
Revert "auto merge of #1356 : ksh8281/servo/remove_@_in_LayoutTask.FontContext, r=pcwalton"
This reverts commit e8ffac13d7e0ebc0701b87b774491b2b1b895607, reversing
changes made to db923feffe4ef1f15c34c2a50acdf74a4321e2d4.
Reverting this change because FreeType is *not* thread safe. See the
documentation here:
http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html
"In multi-threaded applications, make sure that the same FT_Library
object or any of its children doesn't get accessed in parallel."
We will need to use a `MutexArc` instead.
-rw-r--r-- | src/components/gfx/display_list.rs | 13 | ||||
-rw-r--r-- | src/components/gfx/font_context.rs | 1 | ||||
-rw-r--r-- | src/components/gfx/platform/linux/font.rs | 7 | ||||
-rw-r--r-- | src/components/gfx/platform/linux/font_context.rs | 50 | ||||
-rw-r--r-- | src/components/gfx/platform/linux/font_list.rs | 1 | ||||
-rw-r--r-- | src/components/gfx/platform/macos/font_context.rs | 8 | ||||
-rw-r--r-- | src/components/main/layout/box.rs | 52 | ||||
-rw-r--r-- | src/components/main/layout/construct.rs | 30 | ||||
-rw-r--r-- | src/components/main/layout/context.rs | 2 | ||||
-rw-r--r-- | src/components/main/layout/inline.rs | 4 | ||||
-rw-r--r-- | src/components/main/layout/layout_task.rs | 17 | ||||
-rw-r--r-- | src/components/main/layout/text.rs | 18 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 39 |
13 files changed, 120 insertions, 122 deletions
diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs index a477bc71a5d..440659c84d8 100644 --- a/src/components/gfx/display_list.rs +++ b/src/components/gfx/display_list.rs @@ -93,7 +93,7 @@ pub struct SolidColorDisplayItem<E> { /// Renders text. pub struct TextDisplayItem<E> { base: BaseDisplayItem<E>, - text_run: Arc<~TextRun>, + text_run: ~TextRun, range: Range, color: Color, } @@ -163,8 +163,7 @@ impl<E> DisplayItem<E> { debug!("Drawing text at {:?}.", text.base.bounds); // FIXME(pcwalton): Allocating? Why? - let text_run = text.text_run.get(); - let font = render_context.font_ctx.get_font_by_descriptor(&text_run.font_descriptor).unwrap(); + let font = render_context.font_ctx.get_font_by_descriptor(&text.text_run.font_descriptor).unwrap(); let font_metrics = font.with_borrow( |font| { font.metrics.clone() @@ -173,7 +172,7 @@ impl<E> DisplayItem<E> { let baseline_origin = Point2D(origin.x, origin.y + font_metrics.ascent); font.with_mut_borrow( |font| { font.draw_text_into_context(render_context, - text.text_run.get(), + &text.text_run, &text.range, baseline_origin, text.color); @@ -184,18 +183,18 @@ impl<E> DisplayItem<E> { let strikeout_size = font_metrics.strikeout_size; let strikeout_offset = font_metrics.strikeout_offset; - if text_run.decoration.underline { + if text.text_run.decoration.underline { let underline_y = baseline_origin.y - underline_offset; let underline_bounds = Rect(Point2D(baseline_origin.x, underline_y), Size2D(width, underline_size)); render_context.draw_solid_color(&underline_bounds, text.color); } - if text_run.decoration.overline { + if text.text_run.decoration.overline { let overline_bounds = Rect(Point2D(baseline_origin.x, origin.y), Size2D(width, underline_size)); render_context.draw_solid_color(&overline_bounds, text.color); } - if text_run.decoration.line_through { + if text.text_run.decoration.line_through { let strikeout_y = baseline_origin.y - strikeout_offset; let strikeout_bounds = Rect(Point2D(baseline_origin.x, strikeout_y), Size2D(width, strikeout_size)); diff --git a/src/components/gfx/font_context.rs b/src/components/gfx/font_context.rs index 256e31329cc..72b37de0d25 100644 --- a/src/components/gfx/font_context.rs +++ b/src/components/gfx/font_context.rs @@ -31,6 +31,7 @@ pub fn dummy_style() -> FontStyle { } pub trait FontContextHandleMethods { + fn clone(&self) -> FontContextHandle; fn create_font_from_identifier(&self, ~str, UsedFontStyle) -> Result<FontHandle, ()>; } diff --git a/src/components/gfx/platform/linux/font.rs b/src/components/gfx/platform/linux/font.rs index 0f4e2b3b331..cb2573a9a13 100644 --- a/src/components/gfx/platform/linux/font.rs +++ b/src/components/gfx/platform/linux/font.rs @@ -8,6 +8,7 @@ use font::{CSSFontWeight, FontHandleMethods, FontMetrics, FontTableMethods}; use font::{FontTableTag, FractionalPixel, SpecifiedFontStyle, UsedFontStyle, FontWeight100}; use font::{FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600}; use font::{FontWeight700, FontWeight800, FontWeight900}; +use font_context::FontContextHandleMethods; use servo_util::geometry::Au; use servo_util::geometry; use platform::font_context::FontContextHandle; @@ -78,7 +79,7 @@ impl FontHandleMethods for FontHandle { buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> { - let ft_ctx: FT_Library = fctx.ctx.get().ctx; + let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } let face_result = do buf.as_imm_buf |bytes: *u8, len: uint| { @@ -291,7 +292,7 @@ impl<'self> FontHandle { pub fn new_from_file(fctx: &FontContextHandle, file: &str, style: &SpecifiedFontStyle) -> Result<FontHandle, ()> { unsafe { - let ft_ctx: FT_Library = fctx.ctx.get().ctx; + let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } let mut face: FT_Face = ptr::null(); @@ -319,7 +320,7 @@ impl<'self> FontHandle { pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str) -> Result<FontHandle, ()> { unsafe { - let ft_ctx: FT_Library = fctx.ctx.get().ctx; + let ft_ctx: FT_Library = fctx.ctx.ctx; if ft_ctx.is_null() { return Err(()); } let mut face: FT_Face = ptr::null(); diff --git a/src/components/gfx/platform/linux/font_context.rs b/src/components/gfx/platform/linux/font_context.rs index 8fd427ec411..4619454d10d 100644 --- a/src/components/gfx/platform/linux/font_context.rs +++ b/src/components/gfx/platform/linux/font_context.rs @@ -11,23 +11,30 @@ use freetype::freetype::{FTErrorMethods, FT_Library}; use freetype::freetype::{FT_Done_FreeType, FT_Init_FreeType}; use std::ptr; -use extra::arc::Arc; #[deriving(Clone)] struct FreeTypeLibraryHandle { ctx: FT_Library, } -#[deriving(Clone)] +// FIXME(ksh8281) this value have to use atomic operation for counting ref +static mut font_context_ref_count: uint = 0; +static mut ft_pointer: Option<FT_Library> = None; pub struct FontContextHandle { - ctx: Arc<FreeTypeLibraryHandle>, + ctx: FreeTypeLibraryHandle, } -impl Drop for FreeTypeLibraryHandle { +impl Drop for FontContextHandle { #[fixed_stack_segment] fn drop(&mut self) { - assert!(self.ctx.is_not_null()); - unsafe { FT_Done_FreeType(self.ctx) }; + assert!(self.ctx.ctx.is_not_null()); + unsafe { + assert!(font_context_ref_count >= 1); + font_context_ref_count = font_context_ref_count - 1; + if font_context_ref_count == 0 { + FT_Done_FreeType(self.ctx.ctx); + } + } } } @@ -35,17 +42,38 @@ impl FontContextHandle { #[fixed_stack_segment] pub fn new() -> FontContextHandle { unsafe { - let ctx: FT_Library = ptr::null(); - let result = FT_Init_FreeType(&ctx); - if !result.succeeded() { fail!("Unable to initialize FreeType library"); } - FontContextHandle { - ctx: Arc::new(FreeTypeLibraryHandle { ctx: ctx }), + match ft_pointer { + Some(ref ctx) => { + font_context_ref_count = font_context_ref_count + 1; + FontContextHandle { + ctx: FreeTypeLibraryHandle { ctx: ctx.clone() }, + } + }, + None => { + let ctx: FT_Library = ptr::null(); + let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); + if !result.succeeded() { fail!("Unable to initialize FreeType library"); } + ft_pointer = Some(ctx); + font_context_ref_count = font_context_ref_count + 1; + FontContextHandle { + ctx: FreeTypeLibraryHandle { ctx: ctx }, + } + } } } } } impl FontContextHandleMethods for FontContextHandle { + fn clone(&self) -> FontContextHandle { + unsafe { + font_context_ref_count = font_context_ref_count + 1; + FontContextHandle { + ctx: self.ctx.clone() + } + } + } + fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) -> Result<FontHandle, ()> { debug!("Creating font handle for {:s}", name); diff --git a/src/components/gfx/platform/linux/font_list.rs b/src/components/gfx/platform/linux/font_list.rs index deadb966245..74fe4449445 100644 --- a/src/components/gfx/platform/linux/font_list.rs +++ b/src/components/gfx/platform/linux/font_list.rs @@ -19,6 +19,7 @@ use fontconfig::fontconfig::{ use font::{FontHandleMethods, UsedFontStyle}; +use font_context::FontContextHandleMethods; use font_list::{FontEntry, FontFamily, FontFamilyMap}; use platform::font::FontHandle; use platform::font_context::FontContextHandle; diff --git a/src/components/gfx/platform/macos/font_context.rs b/src/components/gfx/platform/macos/font_context.rs index 4a4afe6cefb..0c824073573 100644 --- a/src/components/gfx/platform/macos/font_context.rs +++ b/src/components/gfx/platform/macos/font_context.rs @@ -8,12 +8,10 @@ use platform::macos::font::FontHandle; use core_text; -#[deriving(Clone)] pub struct FontContextHandle { ctx: () } -#[deriving(Clone)] impl FontContextHandle { // this is a placeholder until NSFontManager or whatever is bound in here. pub fn new() -> FontContextHandle { @@ -22,6 +20,12 @@ impl FontContextHandle { } impl FontContextHandleMethods for FontContextHandle { + fn clone(&self) -> FontContextHandle { + FontContextHandle { + ctx: self.ctx + } + } + fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle) diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box.rs index 3159c0863b0..6328328459e 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box.rs @@ -5,7 +5,7 @@ //! The `Box` type, which represents the leaves of the layout tree. use extra::url::Url; -use extra::arc::{MutexArc,Arc}; +use extra::arc::MutexArc; use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use gfx::color::rgb; use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass}; @@ -160,7 +160,7 @@ impl ImageBoxInfo { /// object. pub struct ScannedTextBoxInfo { /// The text run that this represents. - run: Arc<~TextRun>, + run: @TextRun, /// The range within the above text run that this represents. range: Range, @@ -168,7 +168,7 @@ pub struct ScannedTextBoxInfo { impl ScannedTextBoxInfo { /// Creates the information specific to a scanned text box from a range and a text run. - pub fn new(run: Arc<~TextRun>, range: Range) -> ScannedTextBoxInfo { + pub fn new(run: @TextRun, range: Range) -> ScannedTextBoxInfo { ScannedTextBoxInfo { run: run, range: range, @@ -630,12 +630,21 @@ impl Box { // Create the text box. do list.with_mut_ref |list| { + // FIXME(pcwalton): Allocation? Why?! + let run = ~TextRun { + text: text_box.run.text.clone(), + font_descriptor: text_box.run.font_descriptor.clone(), + font_metrics: text_box.run.font_metrics.clone(), + font_style: text_box.run.font_style.clone(), + decoration: text_box.run.decoration.clone(), + glyphs: text_box.run.glyphs.clone() + }; let text_display_item = ~TextDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, extra: ExtraDisplayListData::new(&self), }, - text_run: text_box.run.clone(), + text_run: run, range: text_box.range, color: color, }; @@ -668,7 +677,7 @@ impl Box { // Draw a rectangle representing the baselines. // // TODO(Issue #221): Create and use a Line display item for the baseline. - let ascent = text_box.run.get().metrics_for_range( + let ascent = text_box.run.metrics_for_range( &text_box.range).ascent; let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent), Size2D(absolute_box_bounds.size.width, Au(0))); @@ -781,12 +790,11 @@ impl Box { } ScannedTextBox(ref text_box_info) => { let range = &text_box_info.range; - let text_run = text_box_info.run.get(); - let min_line_width = text_run.min_width_for_range(range); + let min_line_width = text_box_info.run.min_width_for_range(range); let mut max_line_width = Au::new(0); - for line_range in text_run.iter_natural_lines_for_range(range) { - let line_metrics = text_run.metrics_for_range(&line_range); + for line_range in text_box_info.run.iter_natural_lines_for_range(range) { + let line_metrics = text_box_info.run.metrics_for_range(&line_range); max_line_width = Au::max(max_line_width, line_metrics.advance_width); } @@ -816,7 +824,7 @@ impl Box { } ScannedTextBox(ref text_box_info) => { // Compute the height based on the line-height and font size. - let (range, run) = (&text_box_info.range, &text_box_info.run.get()); + let (range, run) = (&text_box_info.range, &text_box_info.run); let text_bounds = run.metrics_for_range(range).bounding_box; let em_size = text_bounds.size.height; self.calculate_line_height(em_size) @@ -838,12 +846,11 @@ impl Box { debug!("split_to_width: splitting text box (strlen={:u}, range={}, \ avail_width={})", - text_box_info.run.get().text.get().len(), + text_box_info.run.text.get().len(), text_box_info.range, max_width); - let text_run = text_box_info.run.get(); - for (glyphs, offset, slice_range) in text_run.iter_slices_for_range( + for (glyphs, offset, slice_range) in text_box_info.run.iter_slices_for_range( &text_box_info.range) { debug!("split_to_width: considering slice (offset={}, range={}, \ remain_width={})", @@ -851,7 +858,7 @@ impl Box { slice_range, remaining_width); - let metrics = text_run.metrics_for_slice(glyphs, &slice_range); + let metrics = text_box_info.run.metrics_for_slice(glyphs, &slice_range); let advance = metrics.advance_width; let should_continue; @@ -902,23 +909,20 @@ impl Box { } let left_box = if left_range.length() > 0 { - - let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run.clone(), left_range); - let new_size = text_box_info.run.get(). - metrics_for_range(&left_range).bounding_box.size; + let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run, left_range); let new_text_box = @Box::new(self.node, ScannedTextBox(new_text_box_info)); - new_text_box.set_size(new_size); + let new_metrics = new_text_box_info.run.metrics_for_range(&left_range); + new_text_box.set_size(new_metrics.bounding_box.size); Some(new_text_box) } else { None }; let right_box = right_range.map_default(None, |range: Range| { - let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run.clone(), range); - let new_size = text_box_info.run.get(). - metrics_for_range(&range).bounding_box.size; + let new_text_box_info = ScannedTextBoxInfo::new(text_box_info.run, range); let new_text_box = @Box::new(self.node, ScannedTextBox(new_text_box_info)); - new_text_box.set_size(new_size); + let new_metrics = new_text_box_info.run.metrics_for_range(&range); + new_text_box.set_size(new_metrics.bounding_box.size); Some(new_text_box) }); @@ -971,7 +975,7 @@ impl Box { /// Cleans up all the memory associated with this box. pub fn teardown(&self) { match self.specific { - ScannedTextBox(ref text_box_info) => text_box_info.run.get().teardown(), + ScannedTextBox(ref text_box_info) => text_box_info.run.teardown(), _ => {} } } diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index e758409c31c..18ff1654888 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -33,7 +33,7 @@ use layout::util::LayoutDataAccess; use script::dom::element::HTMLImageElementTypeId; use script::dom::node::{AbstractNode, CommentNodeTypeId, DoctypeNodeTypeId}; use script::dom::node::{DocumentFragmentNodeTypeId, DocumentNodeTypeId, ElementNodeTypeId}; -use script::dom::node::{LayoutView, PostorderNodeMutTraversal, TextNodeTypeId}; +use script::dom::node::{LayoutView, PostorderNodeTraversal, TextNodeTypeId}; use servo_util::slot::Slot; use servo_util::tree::TreeNodeRef; use std::util; @@ -173,7 +173,7 @@ pub struct FlowConstructor<'self> { /// The layout context. /// /// FIXME(pcwalton): Why does this contain `@`??? That destroys parallelism!!! - layout_context: &'self mut LayoutContext, + layout_context: &'self LayoutContext, /// The next flow ID to assign. /// @@ -183,7 +183,7 @@ pub struct FlowConstructor<'self> { impl<'self> FlowConstructor<'self> { /// Creates a new flow constructor. - pub fn init<'a>(layout_context: &'a mut LayoutContext) -> FlowConstructor<'a> { + pub fn init<'a>(layout_context: &'a LayoutContext) -> FlowConstructor<'a> { FlowConstructor { layout_context: layout_context, next_flow_id: Slot::init(0), @@ -198,7 +198,7 @@ impl<'self> FlowConstructor<'self> { } /// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining. - fn build_box_info_for_image(&mut self, node: AbstractNode<LayoutView>) -> Option<ImageBoxInfo> { + fn build_box_info_for_image(&self, node: AbstractNode<LayoutView>) -> Option<ImageBoxInfo> { // FIXME(pcwalton): Don't copy URLs. let url = node.with_imm_image_element(|image_element| { image_element.image.as_ref().map(|url| (*url).clone()) @@ -215,7 +215,7 @@ impl<'self> FlowConstructor<'self> { } /// Builds a `Box` for the given node. - fn build_box_for_node(&mut self, node: AbstractNode<LayoutView>) -> @Box { + fn build_box_for_node(&self, node: AbstractNode<LayoutView>) -> @Box { let specific = match node.type_id() { ElementNodeTypeId(HTMLImageElementTypeId) => { match self.build_box_info_for_image(node) { @@ -234,7 +234,7 @@ impl<'self> FlowConstructor<'self> { /// `#[inline(always)]` because this is performance critical and LLVM will not inline it /// otherwise. #[inline(always)] - fn flush_inline_boxes_to_flow(&mut self, + fn flush_inline_boxes_to_flow(&self, boxes: ~[@Box], flow: &mut ~Flow:, node: AbstractNode<LayoutView>) { @@ -248,7 +248,7 @@ impl<'self> FlowConstructor<'self> { /// Creates an inline flow from a set of inline boxes, if present, and adds it as a child of /// the given flow. - fn flush_inline_boxes_to_flow_if_necessary(&mut self, + fn flush_inline_boxes_to_flow_if_necessary(&self, opt_boxes: &mut Option<~[@Box]>, flow: &mut ~Flow:, node: AbstractNode<LayoutView>) { @@ -261,7 +261,7 @@ impl<'self> FlowConstructor<'self> { /// Builds the children flows underneath a node with `display: block`. After this call, /// other `BlockFlow`s or `InlineFlow`s will be populated underneath this node, depending on /// whether {ib} splits needed to happen. - fn build_children_of_block_flow(&mut self, + fn build_children_of_block_flow(&self, flow: &mut ~Flow:, node: AbstractNode<LayoutView>) { // Gather up boxes for the inline flows we might need to create. @@ -341,7 +341,7 @@ impl<'self> FlowConstructor<'self> { /// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly /// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed /// to happen. - fn build_flow_for_block(&mut self, node: AbstractNode<LayoutView>) -> ~Flow: { + fn build_flow_for_block(&self, node: AbstractNode<LayoutView>) -> ~Flow: { let base = FlowData::new(self.next_flow_id(), node); let box = self.build_box_for_node(node); let mut flow = ~BlockFlow::from_box(base, box) as ~Flow:; @@ -351,7 +351,7 @@ impl<'self> FlowConstructor<'self> { /// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with /// a `BlockFlow` underneath it. - fn build_flow_for_floated_block(&mut self, node: AbstractNode<LayoutView>, float_type: FloatType) + fn build_flow_for_floated_block(&self, node: AbstractNode<LayoutView>, float_type: FloatType) -> ~Flow: { let base = FlowData::new(self.next_flow_id(), node); let box = self.build_box_for_node(node); @@ -363,7 +363,7 @@ impl<'self> FlowConstructor<'self> { /// Concatenates the boxes of kids, adding in our own borders/padding/margins if necessary. /// Returns the `InlineBoxesConstructionResult`, if any. There will be no /// `InlineBoxesConstructionResult` if this node consisted entirely of ignorable whitespace. - fn build_boxes_for_nonreplaced_inline_content(&mut self, node: AbstractNode<LayoutView>) + fn build_boxes_for_nonreplaced_inline_content(&self, node: AbstractNode<LayoutView>) -> ConstructionResult { let mut opt_inline_block_splits = None; let mut opt_box_accumulator = None; @@ -429,7 +429,7 @@ impl<'self> FlowConstructor<'self> { /// Creates an `InlineBoxesConstructionResult` for replaced content. Replaced content doesn't /// render its children, so this just nukes a child's boxes and creates a `Box`. - fn build_boxes_for_replaced_inline_content(&mut self, node: AbstractNode<LayoutView>) + fn build_boxes_for_replaced_inline_content(&self, node: AbstractNode<LayoutView>) -> ConstructionResult { for kid in node.children() { kid.set_flow_construction_result(NoConstructionResult) @@ -446,7 +446,7 @@ impl<'self> FlowConstructor<'self> { /// Builds one or more boxes for a node with `display: inline`. This yields an /// `InlineBoxesConstructionResult`. - fn build_boxes_for_inline(&mut self, node: AbstractNode<LayoutView>) -> ConstructionResult { + fn build_boxes_for_inline(&self, node: AbstractNode<LayoutView>) -> ConstructionResult { // Is this node replaced content? if !node.is_replaced_content() { // Go to a path that concatenates our kids' boxes. @@ -458,11 +458,11 @@ impl<'self> FlowConstructor<'self> { } } -impl<'self> PostorderNodeMutTraversal for FlowConstructor<'self> { +impl<'self> PostorderNodeTraversal for FlowConstructor<'self> { // `#[inline(always)]` because this is always called from the traversal function and for some // reason LLVM's inlining heuristics go awry here. #[inline(always)] - fn process(&mut self, node: AbstractNode<LayoutView>) -> bool { + fn process(&self, node: AbstractNode<LayoutView>) -> bool { // Get the `display` property for this node, and determine whether this node is floated. let (display, float) = match node.type_id() { ElementNodeTypeId(_) => (node.style().Box.display, node.style().Box.float), diff --git a/src/components/main/layout/context.rs b/src/components/main/layout/context.rs index 2eaa7eafc8c..748ed66d4ad 100644 --- a/src/components/main/layout/context.rs +++ b/src/components/main/layout/context.rs @@ -13,7 +13,7 @@ use extra::arc::MutexArc; /// Data needed by the layout task. pub struct LayoutContext { - font_ctx: ~FontContext, + font_ctx: @mut FontContext, image_cache: MutexArc<LocalImageCache>, screen_size: Rect<Au> } diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index b63b6066d70..11852060d6f 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -702,7 +702,7 @@ impl Flow for InlineFlow { }, ScannedTextBox(ref text_box) => { let range = &text_box.range; - let run = text_box.run.get(); + let run = &text_box.run; // Compute the height based on the line-height and font size let text_bounds = run.metrics_for_range(range).bounding_box; @@ -711,7 +711,7 @@ impl Flow for InlineFlow { // Find the top and bottom of the content area. // Those are used in text-top and text-bottom value of 'vertical-align' - let text_ascent = run.font_metrics.ascent; + let text_ascent = text_box.run.font_metrics.ascent; // Offset from the top of the box is 1/2 of the leading + ascent let text_offset = text_ascent + (line_height - em_size).scale_by(0.5); diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index fdface606fd..d1e8cb63671 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -77,6 +77,9 @@ struct LayoutTask { /// The local image cache. local_image_cache: MutexArc<LocalImageCache>, + /// The local font context. + font_ctx: @mut FontContext, + /// The size of the viewport. screen_size: Option<Size2D<Au>>, @@ -87,8 +90,6 @@ struct LayoutTask { /// The channel on which messages can be sent to the profiler. profiler_chan: ProfilerChan, - - opts: Opts } /// The damage computation traversal. @@ -228,6 +229,7 @@ impl LayoutTask { opts: &Opts, profiler_chan: ProfilerChan) -> LayoutTask { + let fctx = @mut FontContext::new(opts.render_backend, true, profiler_chan.clone()); LayoutTask { id: id, @@ -237,13 +239,13 @@ impl LayoutTask { render_chan: render_chan, image_cache_task: image_cache_task.clone(), local_image_cache: MutexArc::new(LocalImageCache(image_cache_task)), + font_ctx: fctx, screen_size: None, display_list: None, stylist: RWArc::new(new_stylist()), profiler_chan: profiler_chan, - opts: opts.clone() } } @@ -257,8 +259,7 @@ impl LayoutTask { // Create a layout context for use in building display lists, hit testing, &c. fn build_layout_context(&self) -> LayoutContext { let image_cache = self.local_image_cache.clone(); - let font_ctx = ~FontContext::new(self.opts.render_backend, true, - self.profiler_chan.clone()); + let font_ctx = self.font_ctx; let screen_size = self.screen_size.unwrap(); LayoutContext { @@ -343,9 +344,9 @@ impl LayoutTask { /// is intertwined with selector matching, making it difficult to compare directly. It is /// marked `#[inline(never)]` to aid benchmarking in sampling profilers. #[inline(never)] - fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: AbstractNode<LayoutView>) + fn construct_flow_tree(&self, layout_context: &LayoutContext, node: AbstractNode<LayoutView>) -> ~Flow: { - node.traverse_postorder_mut(&mut FlowConstructor::init(layout_context)); + node.traverse_postorder(&FlowConstructor::init(layout_context)); let result = match *node.mutate_layout_data().ptr { Some(ref mut layout_data) => { @@ -440,7 +441,7 @@ impl LayoutTask { // Construct the flow tree. let mut layout_root = profile(time::LayoutTreeBuilderCategory, self.profiler_chan.clone(), - || self.construct_flow_tree(&mut layout_ctx, *node)); + || self.construct_flow_tree(&layout_ctx, *node)); // Propagate damage. layout_root.traverse_preorder(&mut PropagateDamageTraversal { diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index fe49dd7c8c2..e42ede37b56 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -11,7 +11,6 @@ use layout::flow::Flow; use gfx::text::text_run::TextRun; use gfx::text::util::{CompressWhitespaceNewline, transform_text}; use std::vec; -use extra::arc::Arc; use servo_util::range::Range; /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. @@ -26,7 +25,7 @@ impl TextRunScanner { } } - pub fn scan_for_runs(&mut self, ctx: &mut LayoutContext, flow: &mut Flow) { + pub fn scan_for_runs(&mut self, ctx: &LayoutContext, flow: &mut Flow) { { let inline = flow.as_immutable_inline(); // FIXME: this assertion fails on wikipedia, but doesn't seem @@ -76,7 +75,7 @@ impl TextRunScanner { /// responsible for swapping out the list. It is not clear to me (pcwalton) that this is still /// necessary. pub fn flush_clump_to_list(&mut self, - ctx: &mut LayoutContext, + ctx: &LayoutContext, flow: &mut Flow, last_whitespace: bool, out_boxes: &mut ~[@Box]) @@ -126,15 +125,14 @@ impl TextRunScanner { // font group fonts. This is probably achieved by creating the font group above // and then letting `FontGroup` decide which `Font` to stick into the text run. let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style); - let run = Arc::new(~fontgroup.with_borrow(|fg| fg.create_textrun(transformed_text.clone(), decoration))); + let run = @fontgroup.with_borrow(|fg| fg.create_textrun(transformed_text.clone(), decoration)); debug!("TextRunScanner: pushing single text box in range: {} ({})", self.clump, *text); - let range = Range::new(0, run.get().char_len()); - let new_metrics = run.get().metrics_for_range(&range); + let range = Range::new(0, run.char_len()); let new_text_box_info = ScannedTextBoxInfo::new(run, range); - + let new_metrics = run.metrics_for_range(&range); let new_box = @old_box.transform(new_metrics.bounding_box.size, ScannedTextBox(new_text_box_info)); out_boxes.push(new_box) @@ -192,7 +190,7 @@ impl TextRunScanner { let run = if clump.length() != 0 && run_str.len() > 0 { fontgroup.with_borrow( |fg| { fg.fonts[0].with_mut_borrow( |font| { - Some(Arc::new(~TextRun::new(font, run_str.clone(), decoration))) + Some(@TextRun::new(font, run_str.clone(), decoration)) }) }) } else { @@ -210,8 +208,8 @@ impl TextRunScanner { continue } - let new_text_box_info = ScannedTextBoxInfo::new(run.get_ref().clone(), range); - let new_metrics = new_text_box_info.run.get().metrics_for_range(&range); + let new_text_box_info = ScannedTextBoxInfo::new(run.unwrap(), range); + let new_metrics = new_text_box_info.run.metrics_for_range(&range); let new_box = @in_boxes[i].transform(new_metrics.bounding_box.size, ScannedTextBox(new_text_box_info)); out_boxes.push(new_box) diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index a3edd1eb054..b0394528d95 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -1217,20 +1217,6 @@ pub trait PostorderNodeTraversal { } } -/// A bottom-up, parallelizable traversal. -pub trait PostorderNodeMutTraversal { - /// The operation to perform. Return true to continue or false to stop. - fn process(&mut self, node: AbstractNode<LayoutView>) -> bool; - - /// Returns true if this node should be pruned. If this returns true, we skip the operation - /// entirely and do not process any descendant nodes. This is called *before* child nodes are - /// visited. The default implementation never prunes any nodes. - fn should_prune(&self, _node: AbstractNode<LayoutView>) -> bool { - false - } -} - - impl AbstractNode<LayoutView> { /// Traverses the tree in postorder. /// @@ -1255,29 +1241,4 @@ impl AbstractNode<LayoutView> { traversal.process(self) } - - /// Traverses the tree in postorder. - /// - /// TODO(pcwalton): Offer a parallel version with a compatible API. - pub fn traverse_postorder_mut<T:PostorderNodeMutTraversal>(mut self, traversal: &mut T) -> bool { - if traversal.should_prune(self) { - return true - } - - let mut opt_kid = self.first_child(); - loop { - match opt_kid { - None => break, - Some(kid) => { - if !kid.traverse_postorder_mut(traversal) { - return false - } - opt_kid = kid.next_sibling() - } - } - } - - traversal.process(self) - } - } |