diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 5219fe9cd756..e3388a223701 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -649,6 +649,7 @@ impl Flow for BlockFlow { // The text alignment of a block flow is the text alignment of its box's style. self.base.flags_info.flags.set_text_align(style.Text.text_align); + box_.assign_width(remaining_width); // Can compute padding here since we know containing block width. box_.compute_padding(style, remaining_width); @@ -739,6 +740,11 @@ impl Flow for BlockFlow { } fn assign_height(&mut self, ctx: &mut LayoutContext) { + //assign height for box + for box_ in self.box_.iter() { + box_.assign_height(); + } + if self.is_float() { debug!("assign_height_float: assigning height for float {}", self.base.id); self.assign_height_float(ctx); diff --git a/src/components/main/layout/box_.rs b/src/components/main/layout/box_.rs index 4c68e3b0511f..1403fc9d39b1 100644 --- a/src/components/main/layout/box_.rs +++ b/src/components/main/layout/box_.rs @@ -151,7 +151,7 @@ impl ImageBoxInfo { width }, &None => { - fail!("width is not computed yet!"); + fail!("image width is not computed yet!"); } } } @@ -183,7 +183,7 @@ impl ImageBoxInfo { height }, &None => { - fail!("image size is not computed yet!"); + fail!("image height is not computed yet!"); } } } @@ -291,6 +291,7 @@ pub struct InlineParentInfo { style: Arc, font_ascent: Au, font_descent: Au, + node: OpaqueNode, } @@ -511,18 +512,164 @@ impl Box { } pub fn noncontent_width(&self) -> Au { - let left = self.margin.get().left + self.border.get().left + self.padding.get().left; - let right = self.margin.get().right + self.border.get().right + self.padding.get().right; - left + right + self.noncontent_left() + self.noncontent_right() } pub fn noncontent_height(&self) -> Au { - let top = self.margin.get().top + self.border.get().top + self.padding.get().top; - let bottom = self.margin.get().bottom + self.border.get().bottom + - self.padding.get().bottom; - top + bottom + self.noncontent_top() + self.noncontent_bottom() + } + + pub fn noncontent_left(&self) -> Au { + self.margin.get().left + self.border.get().left + self.padding.get().left + } + + pub fn noncontent_right(&self) -> Au { + self.margin.get().right + self.border.get().right + self.padding.get().right + } + + pub fn noncontent_top(&self) -> Au { + self.margin.get().top + self.border.get().top + self.padding.get().top + } + + pub fn noncontent_bottom(&self) -> Au { + self.margin.get().bottom + self.border.get().bottom + self.padding.get().bottom + } + + pub fn noncontent_inline_left(&self) -> Au { + let mut left = Au::new(0); + let info = self.inline_info.borrow(); + match info.get() { + &Some(ref info) => { + for info in info.parent_info.iter() { + left = left + info.margin.left + info.border.left + info.padding.left; + } + }, + &None => {} + } + left + } + + pub fn noncontent_inline_right(&self) -> Au { + let mut right = Au::new(0); + let info = self.inline_info.borrow(); + match info.get() { + &Some(ref info) => { + for info in info.parent_info.iter() { + right = right + info.margin.right + info.border.right + info.padding.right; + } + }, + &None => {} + } + right + } + + pub fn noncontent_inline_top(&self) -> Au { + let mut top = Au::new(0); + let info = self.inline_info.borrow(); + match info.get() { + &Some(ref info) => { + for info in info.parent_info.iter() { + top = top + info.margin.top + info.border.top + info.padding.top; + } + }, + &None => {} + } + top + } + + pub fn noncontent_inline_bottom(&self) -> Au { + let mut bottom = Au::new(0); + let info = self.inline_info.borrow(); + match info.get() { + &Some(ref info) => { + for info in info.parent_info.iter() { + bottom = bottom + info.margin.bottom + info.border.bottom + info.padding.bottom; + } + }, + &None => {} + } + bottom + } + + pub fn merge_noncontent_inline_right(&self, other_box: &Box) { + let mut info = self.inline_info.borrow_mut(); + let other_info = other_box.inline_info.borrow(); + + match other_info.get() { + &Some(ref other_info) => { + match info.get() { + &Some(ref mut info) => { + for other_item in other_info.parent_info.iter() { + for item in info.parent_info.mut_iter() { + if item.node == other_item.node { + item.border.right = other_item.border.right; + item.padding.right = other_item.padding.right; + item.margin.right = other_item.margin.right; + break; + } + } + } + }, + &None => {} + } + }, + &None => {} + } + } + + pub fn merge_noncontent_inline_left(&self, other_box: &Box) { + let mut info = self.inline_info.borrow_mut(); + let other_info = other_box.inline_info.borrow(); + + match other_info.get() { + &Some(ref other_info) => { + match info.get() { + &Some(ref mut info) => { + for other_item in other_info.parent_info.iter() { + for item in info.parent_info.mut_iter() { + if item.node == other_item.node { + item.border.left = other_item.border.left; + item.padding.left = other_item.padding.left; + item.margin.left = other_item.margin.left; + break; + } + } + } + }, + &None => {} + } + }, + &None => {} + } } + pub fn clear_noncontent_inline_right(&self) { + let mut info = self.inline_info.borrow_mut(); + match info.get() { + &Some(ref mut info) => { + for item in info.parent_info.mut_iter() { + item.border.right = Au::new(0); + item.padding.right = Au::new(0); + item.margin.right = Au::new(0); + } + }, + &None => {} + } + } + + pub fn clear_noncontent_inline_left(&self) { + let mut info = self.inline_info.borrow_mut(); + match info.get() { + &Some(ref mut info) => { + for item in info.parent_info.mut_iter() { + item.border.left = Au::new(0); + item.padding.left = Au::new(0); + item.margin.left = Au::new(0); + } + }, + &None => {} + } + } /// Always inline for SCCP. /// /// FIXME(pcwalton): Just replace with the clear type from the style module for speed? @@ -635,9 +782,7 @@ impl Box { (Au::new(0), Au::new(0)) } - /// Adds the display items necessary to paint the background of this box to the display list if - /// necessary. - pub fn paint_background_if_applicable( + pub fn paint_inline_background_border_if_applicable( &self, list: &RefCell>, absolute_bounds: &Rect, @@ -670,11 +815,62 @@ impl Box { list.append_item(SolidColorDisplayItemClass(solid_color_display_item)) }); } + let border = &info.border; + // Fast path. + if border.is_zero() { + continue; + } + bg_rect.origin.y = bg_rect.origin.y - border.top; + bg_rect.size.height = bg_rect.size.height + border.top + border.bottom; + + let style = info.style.get(); + let top_color = style.resolve_color(style.Border.border_top_color); + let right_color = style.resolve_color(style.Border.border_right_color); + let bottom_color = style.resolve_color(style.Border.border_bottom_color); + let left_color = style.resolve_color(style.Border.border_left_color); + let top_style = style.Border.border_top_style; + let right_style = style.Border.border_right_style; + let bottom_style = style.Border.border_bottom_style; + let left_style = style.Border.border_left_style; + + list.with_mut(|list| { + let border_display_item = ~BorderDisplayItem { + base: BaseDisplayItem { + bounds: bg_rect, + extra: ExtraDisplayListData::new(self), + }, + border: border.clone(), + color: SideOffsets2D::new(top_color.to_gfx_color(), + right_color.to_gfx_color(), + bottom_color.to_gfx_color(), + left_color.to_gfx_color()), + style: SideOffsets2D::new(top_style, + right_style, + bottom_style, + left_style) + }; + + list.append_item(BorderDisplayItemClass(border_display_item)) + }); + + bg_rect.origin.x = bg_rect.origin.x + border.left; + bg_rect.size.width = bg_rect.size.width - border.left - border.right; } }, &None => {} } + } + /// Adds the display items necessary to paint the background of this box to the display list if + /// necessary. + pub fn paint_background_if_applicable( + &self, + list: &RefCell>, + absolute_bounds: &Rect) { + // 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 style = self.style(); let background_color = style.resolve_color(style.Background.background_color); if !background_color.alpha.approx_eq(&0.0) { @@ -714,11 +910,16 @@ impl Box { let bottom_style = style.Border.border_bottom_style; let left_style = style.Border.border_left_style; + let mut abs_bounds = abs_bounds.clone(); + abs_bounds.origin.x = abs_bounds.origin.x + self.noncontent_inline_left(); + abs_bounds.size.width = abs_bounds.size.width - self.noncontent_inline_left() + - self.noncontent_inline_right(); + // Append the border to the display list. list.with_mut(|list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { - bounds: *abs_bounds, + bounds: abs_bounds, extra: ExtraDisplayListData::new(self), }, border: border, @@ -774,8 +975,9 @@ impl Box { return; } + self.paint_inline_background_border_if_applicable(list, &absolute_box_bounds, &offset); // Add the background to the list, if applicable. - self.paint_background_if_applicable(list, &absolute_box_bounds, &offset); + self.paint_background_if_applicable(list, &absolute_box_bounds); match self.specific { UnscannedTextBox(_) => fail!("Shouldn't see unscanned boxes here."), @@ -802,7 +1004,6 @@ impl Box { &Some(ref info) => { for data in info.parent_info.rev_iter() { let parent_info = FlowFlagsInfo::new(data.style.get()); - //FIXME(ksh8281) avoid copy flow_flags.propagate_text_decoration_from_parent(&parent_info); } }, @@ -812,12 +1013,19 @@ impl Box { text_flags.set_override_underline(flow_flags.flags.override_underline()); text_flags.set_override_overline(flow_flags.flags.override_overline()); text_flags.set_override_line_through(flow_flags.flags.override_line_through()); + + let mut bounds = absolute_box_bounds.clone(); + bounds.origin.x = bounds.origin.x + self.noncontent_left() + + self.noncontent_inline_left(); + bounds.size.width = bounds.size.width - self.noncontent_width() + - self.noncontent_inline_left() + - self.noncontent_inline_right(); // Create the text box. list.with_mut(|list| { let text_display_item = ~TextDisplayItem { base: BaseDisplayItem { - bounds: absolute_box_bounds, + bounds: bounds, extra: ExtraDisplayListData::new(self), }, text_run: text_box.run.clone(), @@ -924,6 +1132,15 @@ impl Box { }); let mut image_ref = image_box.image.borrow_mut(); + let mut bounds = absolute_box_bounds.clone(); + bounds.origin.x = bounds.origin.x + self.noncontent_left() + + self.noncontent_inline_left(); + bounds.origin.y = bounds.origin.y + self.noncontent_top(); + bounds.size.width = bounds.size.width + - self.noncontent_width() - self.noncontent_inline_left() + - self.noncontent_inline_right(); + bounds.size.height = bounds.size.height - self.noncontent_height(); + match image_ref.get().get_image() { Some(image) => { debug!("(building display list) building image box"); @@ -932,7 +1149,7 @@ impl Box { list.with_mut(|list| { let image_display_item = ~ImageDisplayItem { base: BaseDisplayItem { - bounds: absolute_box_bounds, + bounds: bounds, extra: ExtraDisplayListData::new(self), }, image: image.clone(), @@ -947,6 +1164,26 @@ impl Box { debug!("(building display list) no image :("); } } + // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We + // should have a real `SERVO_DEBUG` system. + debug!("{:?}", { + let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); + + list.with_mut(|list| { + let border_display_item = ~BorderDisplayItem { + base: BaseDisplayItem { + bounds: absolute_box_bounds, + extra: ExtraDisplayListData::new(self), + }, + border: debug_border, + color: SideOffsets2D::new_all_same(rgb(0, 0, 200)), + style: SideOffsets2D::new_all_same(border_style::solid) + + }; + list.append_item(BorderDisplayItemClass(border_display_item)) + }); + }); + } } @@ -1149,7 +1386,8 @@ 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_metrics = new_text_box_info.run.get().metrics_for_range(&left_range); + let mut new_metrics = new_text_box_info.run.get().metrics_for_range(&left_range); + new_metrics.bounding_box.size.height = self.position.get().size.height; Some(self.transform(new_metrics.bounding_box.size, ScannedTextBox(new_text_box_info))) } else { @@ -1158,7 +1396,8 @@ impl Box { 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_metrics = new_text_box_info.run.get().metrics_for_range(&range); + let mut new_metrics = new_text_box_info.run.get().metrics_for_range(&range); + new_metrics.bounding_box.size.height = self.position.get().size.height; Some(self.transform(new_metrics.bounding_box.size, ScannedTextBox(new_text_box_info))) }); @@ -1166,6 +1405,12 @@ impl Box { if pieces_processed_count == 1 || left_box.is_none() { SplitDidNotFit(left_box, right_box) } else { + if left_box.is_some() { + left_box.get_ref().clear_noncontent_inline_right(); + } + if right_box.is_some() { + right_box.get_ref().clear_noncontent_inline_left(); + } SplitDidFit(left_box, right_box) } } @@ -1212,11 +1457,15 @@ impl Box { }; let mut position = self.position.borrow_mut(); - position.get().size.width = width; + position.get().size.width = width + self.noncontent_width() + + self.noncontent_inline_left() + self.noncontent_inline_right(); image_box_info.computed_width.set(Some(width)); } ScannedTextBox(_) => { - // Scanned text boxes will have already had their widths assigned by this point. + // Scanned text boxes will have already had their content_widths assigned by this point. + let mut position = self.position.borrow_mut(); + position.get().size.width = position.get().size.width + self.noncontent_width() + + self.noncontent_inline_left() + self.noncontent_inline_right(); } UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"), } @@ -1252,11 +1501,14 @@ impl Box { }; let mut position = self.position.borrow_mut(); - position.get().size.height = height; image_box_info.computed_height.set(Some(height)); + position.get().size.height = height + self.noncontent_height() } ScannedTextBox(_) => { - // Scanned text boxes will have already had their widths assigned by this point. + // Scanned text boxes will have already had their widths assigned by this point + let mut position = self.position.borrow_mut(); + position.get().size.height + = position.get().size.height + self.noncontent_height() } UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"), } diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index bfc151fb012a..e2605e6bd6ca 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -29,7 +29,7 @@ use layout::float_context::FloatType; use layout::flow::{BaseFlow, Flow, LeafSet, MutableOwnedFlowUtils}; use layout::inline::InlineFlow; use layout::text::TextRunScanner; -use layout::util::LayoutDataAccess; +use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::wrapper::{LayoutNode, PostorderNodeMutTraversal}; use gfx::font_context::FontContext; @@ -425,7 +425,7 @@ impl<'fc> FlowConstructor<'fc> { -> ConstructionResult { let mut opt_inline_block_splits = None; let mut opt_box_accumulator = None; - + // Concatenate all the boxes of our kids, creating {ib} splits as necessary. for kid in node.children() { match kid.swap_out_construction_result() { @@ -442,10 +442,8 @@ impl<'fc> FlowConstructor<'fc> { ConstructionItemConstructionResult(InlineBoxesConstructionItem( InlineBoxesConstructionResult { splits: opt_splits, - boxes: mut boxes + boxes: boxes })) => { - // fill inline info - self.set_inline_info_for_inline_child(&mut boxes, node); // Bubble up {ib} splits. match opt_splits { @@ -474,6 +472,49 @@ impl<'fc> FlowConstructor<'fc> { } } + // fill inline info + match opt_inline_block_splits { + Some(ref splits) => { + match opt_box_accumulator { + Some(ref boxes) => { + // Both + let mut total: ~[&Box] = ~[]; + for split in splits.iter() { + for box_ in split.predecessor_boxes.iter() { + total.push(box_); + } + } + for box_ in boxes.iter() { + total.push(box_); + } + self.set_inline_info_for_inline_child(&total, node); + + }, + None => { + let mut total: ~[&Box] = ~[]; + for split in splits.iter() { + for box_ in split.predecessor_boxes.iter() { + total.push(box_); + } + } + self.set_inline_info_for_inline_child(&total, node); + } + } + }, + None => { + match opt_box_accumulator { + Some(ref boxes) => { + let mut total: ~[&Box] = ~[]; + for box_ in boxes.iter() { + total.push(box_); + } + self.set_inline_info_for_inline_child(&total, node); + }, + None => {} + } + } + } + // Finally, make a new construction result. if opt_inline_block_splits.len() > 0 || opt_box_accumulator.len() > 0 { let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult { @@ -486,7 +527,7 @@ impl<'fc> FlowConstructor<'fc> { } } - fn set_inline_info_for_inline_child(&mut self, boxes: &mut ~[Box], parent_node: LayoutNode) { + fn set_inline_info_for_inline_child(&mut self, boxes: &~[&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.font_context.get_resolved_font_for_style(&font_style); @@ -496,23 +537,35 @@ impl<'fc> FlowConstructor<'fc> { }) }); - for box_ in boxes.mut_iter() { + let boxes_len = boxes.len(); + parent_box.compute_borders(parent_box.style()); + + for (i,box_) in boxes.iter().enumerate() { if box_.inline_info.with( |data| data.is_none() ) { box_.inline_info.set(Some(InlineInfo::new())); } + let mut border = parent_box.border.get(); + if i != 0 { + border.left = Zero::zero(); + } + if i != (boxes_len - 1) { + border.right = Zero::zero(); + } + let mut info = box_.inline_info.borrow_mut(); match info.get() { &Some(ref mut info) => { - // TODO(ksh8281) compute margin,border,padding + // TODO(ksh8281) compute margin,padding info.parent_info.push( InlineParentInfo { padding: Zero::zero(), - border: Zero::zero(), + border: border, margin: Zero::zero(), style: parent_box.style.clone(), font_ascent: font_ascent, font_descent: font_descent, + node: OpaqueNode::from_layout_node(&parent_node), }); }, &None => {} @@ -670,13 +723,22 @@ fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) { // FIXME(pcwalton): This is slow because vector shift is broken. :( let mut found_nonwhitespace = false; let mut result = ~[]; + let mut last_removed_box: Option = None; for box_ in boxes.move_iter() { if !found_nonwhitespace && box_.is_whitespace_only() { debug!("stripping ignorable whitespace from start"); + last_removed_box = Some(box_); continue } found_nonwhitespace = true; + match last_removed_box { + Some(ref last_removed_box) => { + box_.merge_noncontent_inline_left(last_removed_box); + }, + None => {} + } + last_removed_box = None; result.push(box_) } @@ -692,7 +754,10 @@ fn strip_ignorable_whitespace_from_end(opt_boxes: &mut Option<~[Box]>) { Some(ref mut boxes) => { while boxes.len() > 0 && boxes.last().is_whitespace_only() { debug!("stripping ignorable whitespace from end"); - let _ = boxes.pop(); + let box_ = boxes.pop(); + if boxes.len() > 0 { + boxes[boxes.len() - 1].merge_noncontent_inline_right(&box_); + } } } } diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs index 3a7931aaf0c1..175baeddea64 100644 --- a/src/components/main/layout/flow.rs +++ b/src/components/main/layout/flow.rs @@ -363,6 +363,7 @@ impl FlowFlagsInfo { if !self.flags.is_text_decoration_enabled() && parent.flags.is_text_decoration_enabled() { self.rare_flow_flags = parent.rare_flow_flags.clone(); + self.flags.set_text_decoration_override(parent.flags); return ; } diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index d33285104604..b592d1084499 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -646,6 +646,7 @@ impl Flow for InlineFlow { for box_ in self.boxes.iter() { debug!("Flow[{:d}]: measuring {:s}", self.base.id, box_.debug_str()); + box_.compute_borders(box_.style()); let (this_minimum_width, this_preferred_width) = box_.minimum_and_preferred_widths(); min_width = Au::max(min_width, this_minimum_width); @@ -710,7 +711,6 @@ impl Flow for InlineFlow { // // TODO(pcwalton): Cache the linebox scanner? debug!("assign_height_inline: floats_in: {:?}", self.base.floats_in); - // assign height for inline boxes for box_ in self.boxes.iter() { box_.assign_height(); @@ -720,7 +720,6 @@ impl Flow for InlineFlow { // Access the linebox scanner. scanner.scan_for_lines(self); - let mut line_height_offset = Au::new(0); // All lines use text alignment of the flow. @@ -743,6 +742,7 @@ impl Flow for InlineFlow { for box_i in line.range.eachi() { let cur_box = &self.boxes[box_i]; + let top = cur_box.noncontent_top(); // FIXME(pcwalton): Move into `box.rs` like the rest of box-specific layout code? let (top_from_base, bottom_from_base, ascent) = match cur_box.specific { @@ -751,22 +751,10 @@ impl Flow for InlineFlow { // TODO: margin, border, padding's top and bottom should be calculated in // advance, since baseline of image is bottom margin edge. - let mut top; - let mut bottom; - { - top = cur_box.border.get().top + cur_box.padding.get().top + - cur_box.margin.get().top; - bottom = cur_box.border.get().bottom + cur_box.padding.get().bottom + - cur_box.margin.get().bottom; - } - + let bottom = cur_box.noncontent_bottom(); let noncontent_height = top + bottom; height = height + noncontent_height; - let mut position_ref = cur_box.position.borrow_mut(); - position_ref.get().size.height = height; - position_ref.get().translate(&Point2D(Au::new(0), -height)); - let ascent = height + bottom; (height, Au::new(0), ascent) }, @@ -845,7 +833,7 @@ impl Flow for InlineFlow { bottommost = bottom_from_base; } - cur_box.position.borrow_mut().get().origin.y = line.bounds.origin.y + offset; + cur_box.position.borrow_mut().get().origin.y = line.bounds.origin.y + offset + top; } // Calculate the distance from baseline to the top of the biggest box with 'bottom' diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index b8913c6499e1..d4f5e242db5f 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -18,12 +18,14 @@ use style::computed_values::white_space; /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. pub struct TextRunScanner { clump: Range, + last_lost_box_index: Option } impl TextRunScanner { pub fn new() -> TextRunScanner { TextRunScanner { clump: Range::empty(), + last_lost_box_index: None, } } @@ -102,7 +104,8 @@ impl TextRunScanner { (true, false) => { // FIXME(pcwalton): Stop cloning boxes, as above. debug!("TextRunScanner: pushing single non-text box in range: {}", self.clump); - out_boxes.push(in_boxes[self.clump.begin()].clone()); + let new_box = in_boxes[self.clump.begin()].clone(); + self.push_to_outboxes(new_box,in_boxes,out_boxes); }, (true, true) => { let old_box = &in_boxes[self.clump.begin()]; @@ -145,7 +148,9 @@ impl TextRunScanner { let mut new_box = old_box.transform(new_metrics.bounding_box.size, ScannedTextBox(new_text_box_info)); new_box.new_line_pos = new_line_pos; - out_boxes.push(new_box) + self.push_to_outboxes(new_box,in_boxes,out_boxes); + } else { + self.last_lost_box_index = Some(self.clump.begin()); } }, (false, true) => { @@ -237,7 +242,7 @@ impl TextRunScanner { let mut new_box = in_boxes[i].transform(new_metrics.bounding_box.size, ScannedTextBox(new_text_box_info)); new_box.new_line_pos = new_line_positions[logical_offset].new_line_pos.clone(); - out_boxes.push(new_box) + self.push_to_outboxes(new_box,in_boxes,out_boxes); } } } // End of match. @@ -265,4 +270,15 @@ impl TextRunScanner { new_whitespace } // End of `flush_clump_to_list`. + + fn push_to_outboxes(&mut self, new_box: Box, in_boxes: &~[Box], out_boxes: &mut ~[Box]) { + match self.last_lost_box_index { + Some(index) => { + new_box.merge_noncontent_inline_left(&in_boxes[index]); + }, + None => {} + } + self.last_lost_box_index = None; + out_boxes.push(new_box) + } } diff --git a/src/test/html/test_inline_border.html b/src/test/html/test_inline_border.html index 7d0e8cdfefbf..9558595282d3 100644 --- a/src/test/html/test_inline_border.html +++ b/src/test/html/test_inline_border.html @@ -1,12 +1,16 @@ - + hi there? -hi there +

+ + + kitty? + + this is em + + +