mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
initial implement for inline background
This commit is contained in:
parent
32bf796efc
commit
25a3da6180
4 changed files with 124 additions and 7 deletions
|
@ -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,44 @@ 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".
|
||||
|
||||
|
||||
self.inline_info.with( |info| {
|
||||
match info {
|
||||
&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 +664,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."),
|
||||
|
|
|
@ -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,44 @@ impl<'fc> FlowConstructor<'fc> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO(pcwalton): Add in our own borders/padding/margins if necessary.
|
||||
match opt_box_accumulator {
|
||||
Some(ref mut boxes) => {
|
||||
let parent_box = self.build_box_for_node(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()));
|
||||
}
|
||||
|
||||
box_.inline_info.with_mut( |info| {
|
||||
match info {
|
||||
&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 => {}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
// Finally, make a new construction result.
|
||||
if opt_inline_block_splits.len() > 0 || opt_box_accumulator.len() > 0 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue