diff options
author | bors-servo <release+servo@mozilla.com> | 2014-01-15 18:20:51 -0800 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-01-15 18:20:51 -0800 |
commit | 87b25f9c2b149b5bd308a4f9d45620e2a604d1dd (patch) | |
tree | b43c75f790d108ec09caf4984333ff49eeb7bc0e /src | |
parent | 8b22019d47bb655f41e70b120a5a40b4290292f5 (diff) | |
parent | 6364103d294f06fa88b5369d5fb0c2f2fccf0727 (diff) | |
download | servo-87b25f9c2b149b5bd308a4f9d45620e2a604d1dd.tar.gz servo-87b25f9c2b149b5bd308a4f9d45620e2a604d1dd.zip |
auto merge of #1494 : ksh8281/servo/inline_add, r=pcwalton
initial implement for inline background
it makes same result in "src/test/html/inline_bg_color_simple.html" with firefox
Diffstat (limited to 'src')
-rw-r--r-- | src/components/main/layout/box_.rs | 69 | ||||
-rw-r--r-- | src/components/main/layout/construct.rs | 43 | ||||
-rw-r--r-- | src/components/main/layout/inline.rs | 15 | ||||
-rw-r--r-- | src/test/html/inline_bg_color_simple.html | 2 |
4 files changed, 122 insertions, 7 deletions
diff --git a/src/components/main/layout/box_.rs b/src/components/main/layout/box_.rs index 57eed410b6a..bd7ba5bd000 100644 --- a/src/components/main/layout/box_.rs +++ b/src/components/main/layout/box_.rs @@ -88,6 +88,9 @@ pub struct Box { /// positioned box offsets position_offsets: RefCell<SideOffsets2D<Au>>, + + /// Inline data + inline_info: RefCell<Option<InlineInfo>>, } /// Info specific to the kind of box. Keep this enum small. @@ -224,6 +227,34 @@ pub enum SplitBoxResult { SplitDidNotFit(Option<Box>, Option<Box>) } + +/// data for inline boxes +#[deriving(Clone)] +pub struct InlineInfo { + parent_info: ~[InlineParentInfo], + baseline: Au, +} + +impl InlineInfo { + pub fn new() -> InlineInfo { + InlineInfo { + parent_info: ~[], + baseline: Au::new(0), + } + } +} + +#[deriving(Clone)] +pub struct InlineParentInfo { + padding: SideOffsets2D<Au>, + border: SideOffsets2D<Au>, + margin: SideOffsets2D<Au>, + style: Arc<ComputedValues>, + font_ascent: Au, + font_descent: Au, +} + + impl Box { /// Constructs a new `Box` instance. pub fn new(node: LayoutNode, specific: SpecificBoxInfo) -> Box { @@ -263,6 +294,7 @@ impl Box { margin: RefCell::new(Zero::zero()), specific: specific, position_offsets: RefCell::new(Zero::zero()), + inline_info: RefCell::new(None), } } @@ -285,7 +317,8 @@ impl Box { padding: RefCell::new(self.padding.get()), margin: RefCell::new(self.margin.get()), specific: specific, - position_offsets: RefCell::new(Zero::zero()) + position_offsets: RefCell::new(Zero::zero()), + inline_info: self.inline_info.clone(), } } @@ -493,11 +526,41 @@ impl Box { pub fn paint_background_if_applicable<E:ExtraDisplayListData>( &self, list: &RefCell<DisplayList<E>>, - absolute_bounds: &Rect<Au>) { + absolute_bounds: &Rect<Au>, + offset: &Point2D<Au>) { // FIXME: This causes a lot of background colors to be displayed when they are clearly not // needed. We could use display list optimization to clean this up, but it still seems // inefficient. What we really want is something like "nearest ancestor element that // doesn't have a box". + let info = self.inline_info.borrow(); + match info.get() { + &Some(ref box_info) => { + let mut bg_rect = absolute_bounds.clone(); + for info in box_info.parent_info.rev_iter() { + // TODO (ksh8281) compute vertical-align, line-height + bg_rect.origin.y = box_info.baseline + offset.y - info.font_ascent; + bg_rect.size.height = info.font_ascent + info.font_descent; + let background_color = info.style.get().resolve_color( + info.style.get().Background.background_color); + + if !background_color.alpha.approx_eq(&0.0) { + list.with_mut(|list| { + let solid_color_display_item = ~SolidColorDisplayItem { + base: BaseDisplayItem { + bounds: bg_rect.clone(), + extra: ExtraDisplayListData::new(self), + }, + color: background_color.to_gfx_color(), + }; + + list.append_item(SolidColorDisplayItemClass(solid_color_display_item)) + }); + } + + } + }, + &None => {} + } let style = self.style(); let background_color = style.resolve_color(style.Background.background_color); if !background_color.alpha.approx_eq(&0.0) { @@ -598,7 +661,7 @@ impl Box { } // Add the background to the list, if applicable. - self.paint_background_if_applicable(list, &absolute_box_bounds); + self.paint_background_if_applicable(list, &absolute_box_bounds, &offset); match self.specific { UnscannedTextBox(_) => fail!("Shouldn't see unscanned boxes here."), diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index 3c65a6363a7..017dffecd0b 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -23,7 +23,7 @@ use css::node_style::StyledNode; use layout::block::BlockFlow; use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo}; -use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo}; +use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo, InlineInfo, InlineParentInfo}; use layout::context::LayoutContext; use layout::float_context::FloatType; use layout::flow::{BaseFlow, Flow, MutableFlowUtils}; @@ -39,6 +39,7 @@ use style::computed_values::{display, float}; use std::cell::RefCell; use std::util; +use std::num::Zero; /// The results of flow construction for a DOM node. pub enum ConstructionResult { @@ -415,7 +416,12 @@ impl<'fc> FlowConstructor<'fc> { } } - // TODO(pcwalton): Add in our own borders/padding/margins if necessary. + match opt_box_accumulator { + Some(ref mut boxes) => { + self.set_inline_info_for_inline_child(boxes, node) + }, + None => {} + } // Finally, make a new construction result. if opt_inline_block_splits.len() > 0 || opt_box_accumulator.len() > 0 { @@ -429,6 +435,39 @@ impl<'fc> FlowConstructor<'fc> { } } + fn set_inline_info_for_inline_child(&mut self, boxes: &mut ~[Box], parent_node: LayoutNode) { + let parent_box = self.build_box_for_node(parent_node); + let font_style = parent_box.font_style(); + let font_group = self.layout_context.font_ctx.get_resolved_font_for_style(&font_style); + let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| { + fg.fonts[0].borrow().with_mut( |font| { + (font.metrics.ascent,font.metrics.descent) + }) + }); + + for box_ in boxes.mut_iter() { + if box_.inline_info.with( |data| data.is_none() ) { + box_.inline_info.set(Some(InlineInfo::new())); + } + + let mut info = box_.inline_info.borrow_mut(); + match info.get() { + &Some(ref mut info) => { + // TODO(ksh8281) compute margin,border,padding + info.parent_info.push( + InlineParentInfo { + padding: Zero::zero(), + border: Zero::zero(), + margin: Zero::zero(), + style: parent_box.style.clone(), + font_ascent: font_ascent, + font_descent: font_descent, + }); + }, + &None => {} + } + } + } /// 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: LayoutNode) -> ConstructionResult { diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index 576b727cd44..28da9b58a26 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -4,7 +4,7 @@ use css::node_style::StyledNode; use layout::box_::{Box, CannotSplit, GenericBox, IframeBox, ImageBox, ScannedTextBox, SplitDidFit}; -use layout::box_::{SplitDidNotFit, UnscannedTextBox}; +use layout::box_::{SplitDidNotFit, UnscannedTextBox, InlineInfo}; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::flow::{BaseFlow, FlowClass, Flow, InlineFlowClass}; @@ -837,6 +837,19 @@ impl Flow for InlineFlow { cur_box.position.borrow_mut().get().origin.y = cur_box.position.get().origin.y + adjust_offset; + + if cur_box.inline_info.with(|info| info.is_none()) { + cur_box.inline_info.set(Some(InlineInfo::new())); + } + cur_box.inline_info.with_mut( |info| { + match info { + &Some(ref mut info) => { + // TODO (ksh8281) compute vertical-align, line-height + info.baseline = line.bounds.origin.y + baseline_offset; + }, + &None => {} + } + }); } // This is used to set the top y position of the next linebox in the next loop. diff --git a/src/test/html/inline_bg_color_simple.html b/src/test/html/inline_bg_color_simple.html index 5f145e64e96..7d6efcfbe0d 100644 --- a/src/test/html/inline_bg_color_simple.html +++ b/src/test/html/inline_bg_color_simple.html @@ -5,7 +5,7 @@ <p style="background-color:yellow">paragraph yellow</p> [inline background color test] - <span style="background-color:blue;">span blue</span>texttexttext<span style="background-color:yellow;">span yellow<span style="background-color:red">nested-span red</span>test finishes</span> + <span style="font-size:30px;background-color:blue;"><img src="test.jpeg"/> span bluetexttexttext<span style="font-size:50px;background-color:yellow;">span yellow<span style="font-size:15px;background-color:red">nested-span red</span>test finishes</span></span> </body> </html> |