aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2014-01-15 18:20:51 -0800
committerbors-servo <release+servo@mozilla.com>2014-01-15 18:20:51 -0800
commit87b25f9c2b149b5bd308a4f9d45620e2a604d1dd (patch)
treeb43c75f790d108ec09caf4984333ff49eeb7bc0e /src
parent8b22019d47bb655f41e70b120a5a40b4290292f5 (diff)
parent6364103d294f06fa88b5369d5fb0c2f2fccf0727 (diff)
downloadservo-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_.rs69
-rw-r--r--src/components/main/layout/construct.rs43
-rw-r--r--src/components/main/layout/inline.rs15
-rw-r--r--src/test/html/inline_bg_color_simple.html2
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>