mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Move InlineFlow's lines and elems mappings to use Range
This commit is contained in:
parent
fcca6d6ada
commit
adeae3c46c
3 changed files with 44 additions and 44 deletions
|
@ -12,6 +12,7 @@ use layout::context::LayoutContext;
|
||||||
use layout::debug::BoxedDebugMethods;
|
use layout::debug::BoxedDebugMethods;
|
||||||
use layout::inline::InlineFlowData;
|
use layout::inline::InlineFlowData;
|
||||||
use layout::root::RootFlowData;
|
use layout::root::RootFlowData;
|
||||||
|
use util::range::{Range, MutableRange};
|
||||||
use util::tree;
|
use util::tree;
|
||||||
|
|
||||||
/** Servo's experimental layout system builds a tree of FlowContexts
|
/** Servo's experimental layout system builds a tree of FlowContexts
|
||||||
|
@ -179,12 +180,9 @@ impl BoxConsumer {
|
||||||
let final_span_length = self.flow.inline().boxes.len() - entry.start_idx + 1;
|
let final_span_length = self.flow.inline().boxes.len() - entry.start_idx + 1;
|
||||||
assert final_span_length > 1;
|
assert final_span_length > 1;
|
||||||
let mapping = { node: copy box.d().node,
|
let mapping = { node: copy box.d().node,
|
||||||
span: {
|
range: MutableRange(entry.start_idx, final_span_length)
|
||||||
mut start: entry.start_idx as u16,
|
|
||||||
mut len: final_span_length as u16
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
debug!("BoxConsumer: adding element range=%?", mapping.span);
|
debug!("BoxConsumer: adding element range=%?", mapping.range);
|
||||||
self.flow.inline().elems.push(mapping);
|
self.flow.inline().elems.push(mapping);
|
||||||
},
|
},
|
||||||
@BlockFlow(*) => {
|
@BlockFlow(*) => {
|
||||||
|
|
|
@ -41,12 +41,7 @@ serve as the starting point, but the current design doesn't make it
|
||||||
hard to try out that alternative.
|
hard to try out that alternative.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type BoxRange = {mut start: u16, mut len: u16};
|
type NodeRange = {node: Node, range: MutableRange};
|
||||||
fn EmptyBoxRange() -> BoxRange {
|
|
||||||
{ mut start: 0 as u16, mut len: 0 as u16 }
|
|
||||||
}
|
|
||||||
|
|
||||||
type NodeRange = {node: Node, span: BoxRange};
|
|
||||||
|
|
||||||
// stack-allocated object for scanning an inline flow into
|
// stack-allocated object for scanning an inline flow into
|
||||||
// TextRun-containing TextBoxes.
|
// TextRun-containing TextBoxes.
|
||||||
|
@ -190,26 +185,24 @@ impl TextRunScanner {
|
||||||
|
|
||||||
// then, fix NodeRange mappings to account for elided boxes.
|
// then, fix NodeRange mappings to account for elided boxes.
|
||||||
do self.flow.inline().elems.borrow |ranges: &[NodeRange]| {
|
do self.flow.inline().elems.borrow |ranges: &[NodeRange]| {
|
||||||
for ranges.each |range: &NodeRange| {
|
for ranges.each |node_range: &NodeRange| {
|
||||||
let span = &range.span;
|
let range = &node_range.range;
|
||||||
let relation = relation_of_clump_and_range(span, self.clump_start, self.clump_end);
|
let relation = relation_of_clump_and_range(range.as_immutable(), self.clump_start, self.clump_end);
|
||||||
debug!("TextRunScanner: possibly repairing element range %?", range.span);
|
debug!("TextRunScanner: possibly repairing element range %?", node_range.range);
|
||||||
debug!("TextRunScanner: relation of range and clump(start=%u, end=%u): %?",
|
debug!("TextRunScanner: relation of range and clump(start=%u, end=%u): %?",
|
||||||
self.clump_start, self.clump_end, relation);
|
self.clump_start, self.clump_end, relation);
|
||||||
match relation {
|
match relation {
|
||||||
RangeEntirelyBeforeClump => {},
|
RangeEntirelyBeforeClump => {},
|
||||||
RangeEntirelyAfterClump => { span.start -= clump_box_count as u16; },
|
RangeEntirelyAfterClump => { range.shift_by(-clump_box_count as int); },
|
||||||
RangeCoincidesClump | RangeContainedByClump =>
|
RangeCoincidesClump | RangeContainedByClump =>
|
||||||
{ span.start = self.clump_start as u16;
|
{ range.reset(self.clump_start, 1); },
|
||||||
span.len = 1 },
|
RangeContainsClump => { range.extend_by(-(clump_box_count as int)); },
|
||||||
RangeContainsClump => { span.len -= clump_box_count as u16; },
|
|
||||||
RangeOverlapsClumpStart(overlap) =>
|
RangeOverlapsClumpStart(overlap) =>
|
||||||
{ span.len -= (overlap - 1) as u16; },
|
{ range.extend_by(1 - (overlap as int)); },
|
||||||
RangeOverlapsClumpEnd(overlap) =>
|
RangeOverlapsClumpEnd(overlap) =>
|
||||||
{ span.start = self.clump_start as u16;
|
{ range.reset(self.clump_start, 1 + range.length() - overlap); }
|
||||||
span.len -= (overlap - 1) as u16; }
|
|
||||||
}
|
}
|
||||||
debug!("TextRunScanner: new element range: ---- %?", range.span);
|
debug!("TextRunScanner: new element range: ---- %?", node_range.range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,10 +233,10 @@ impl TextRunScanner {
|
||||||
RangeEntirelyAfterClump
|
RangeEntirelyAfterClump
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relation_of_clump_and_range(range: &BoxRange, clump_start: uint,
|
fn relation_of_clump_and_range(range: Range, clump_start: uint,
|
||||||
clump_end: uint) -> ClumpRangeRelation {
|
clump_end: uint) -> ClumpRangeRelation {
|
||||||
let range_start = range.start as uint;
|
let range_start = range.begin();
|
||||||
let range_end = (range.start + range.len) as uint;
|
let range_end = (range.begin() + range.length());
|
||||||
|
|
||||||
if range_end < clump_start {
|
if range_end < clump_start {
|
||||||
return RangeEntirelyBeforeClump;
|
return RangeEntirelyBeforeClump;
|
||||||
|
@ -278,8 +271,8 @@ struct LineboxScanner {
|
||||||
flow: @FlowContext,
|
flow: @FlowContext,
|
||||||
new_boxes: DVec<@RenderBox>,
|
new_boxes: DVec<@RenderBox>,
|
||||||
work_list: DList<@RenderBox>,
|
work_list: DList<@RenderBox>,
|
||||||
mut pending_line: {span: BoxRange, width: au},
|
pending_line: {range: MutableRange, mut width: au},
|
||||||
line_spans: DVec<BoxRange>
|
line_spans: DVec<Range>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn LineboxScanner(inline: @FlowContext) -> LineboxScanner {
|
fn LineboxScanner(inline: @FlowContext) -> LineboxScanner {
|
||||||
|
@ -289,21 +282,26 @@ fn LineboxScanner(inline: @FlowContext) -> LineboxScanner {
|
||||||
flow: inline,
|
flow: inline,
|
||||||
new_boxes: DVec(),
|
new_boxes: DVec(),
|
||||||
work_list: DList(),
|
work_list: DList(),
|
||||||
pending_line: {span: EmptyBoxRange(), width: au(0)},
|
pending_line: {range: util::range::empty_mut(), mut width: au(0)},
|
||||||
line_spans: DVec()
|
line_spans: DVec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineboxScanner {
|
impl LineboxScanner {
|
||||||
fn reset() {
|
priv fn reset_scanner() {
|
||||||
debug!("Resetting line box scanner's state for flow f%d.", self.flow.d().id);
|
debug!("Resetting line box scanner's state for flow f%d.", self.flow.d().id);
|
||||||
do self.line_spans.swap |_v| { ~[] };
|
do self.line_spans.swap |_v| { ~[] };
|
||||||
do self.new_boxes.swap |_v| { ~[] };
|
do self.new_boxes.swap |_v| { ~[] };
|
||||||
self.pending_line = {span: EmptyBoxRange(), width: au(0)};
|
self.reset_linebox();
|
||||||
|
}
|
||||||
|
|
||||||
|
priv fn reset_linebox() {
|
||||||
|
self.pending_line.range.reset(0,0);
|
||||||
|
self.pending_line.width = au(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scan_for_lines(ctx: &LayoutContext) {
|
pub fn scan_for_lines(ctx: &LayoutContext) {
|
||||||
self.reset();
|
self.reset_scanner();
|
||||||
|
|
||||||
let boxes = &self.flow.inline().boxes;
|
let boxes = &self.flow.inline().boxes;
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
|
@ -333,7 +331,7 @@ impl LineboxScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.pending_line.span.len > 0 {
|
if self.pending_line.range.length() > 0 {
|
||||||
debug!("LineboxScanner: Partially full linebox %u left at end of scanning.",
|
debug!("LineboxScanner: Partially full linebox %u left at end of scanning.",
|
||||||
self.line_spans.len());
|
self.line_spans.len());
|
||||||
self.flush_current_line();
|
self.flush_current_line();
|
||||||
|
@ -357,13 +355,13 @@ impl LineboxScanner {
|
||||||
debug!("LineboxScanner: Flushing line %u: %?",
|
debug!("LineboxScanner: Flushing line %u: %?",
|
||||||
self.line_spans.len(), self.pending_line);
|
self.line_spans.len(), self.pending_line);
|
||||||
// set box horizontal offsets
|
// set box horizontal offsets
|
||||||
let line_span = copy self.pending_line.span;
|
let line_range = self.pending_line.range.as_immutable();
|
||||||
let mut offset_x = au(0);
|
let mut offset_x = au(0);
|
||||||
// TODO: interpretation of CSS 'text-direction' and 'text-align'
|
// TODO: interpretation of CSS 'text-direction' and 'text-align'
|
||||||
// will change from which side we start laying out the line.
|
// will change from which side we start laying out the line.
|
||||||
debug!("LineboxScanner: Setting horizontal offsets for boxes in line %u range: %?",
|
debug!("LineboxScanner: Setting horizontal offsets for boxes in line %u range: %?",
|
||||||
self.line_spans.len(), line_span);
|
self.line_spans.len(), line_range);
|
||||||
for uint::range(line_span.start as uint, (line_span.start + line_span.len) as uint) |i| {
|
for line_range.eachi |i| {
|
||||||
let box_data = &self.new_boxes[i].d();
|
let box_data = &self.new_boxes[i].d();
|
||||||
box_data.position.origin.x = offset_x;
|
box_data.position.origin.x = offset_x;
|
||||||
offset_x += box_data.position.size.width;
|
offset_x += box_data.position.size.width;
|
||||||
|
@ -371,15 +369,15 @@ impl LineboxScanner {
|
||||||
|
|
||||||
// clear line and add line mapping
|
// clear line and add line mapping
|
||||||
debug!("LineboxScanner: Saving information for flushed line %u.", self.line_spans.len());
|
debug!("LineboxScanner: Saving information for flushed line %u.", self.line_spans.len());
|
||||||
self.line_spans.push(copy self.pending_line.span);
|
self.line_spans.push(line_range);
|
||||||
self.pending_line = {span: EmptyBoxRange(), width: au(0)};
|
self.reset_linebox();
|
||||||
}
|
}
|
||||||
|
|
||||||
// return value: whether any box was appended.
|
// return value: whether any box was appended.
|
||||||
priv fn try_append_to_line(ctx: &LayoutContext, in_box: @RenderBox) -> bool {
|
priv fn try_append_to_line(ctx: &LayoutContext, in_box: @RenderBox) -> bool {
|
||||||
let remaining_width = self.flow.d().position.size.width - self.pending_line.width;
|
let remaining_width = self.flow.d().position.size.width - self.pending_line.width;
|
||||||
let in_box_width = in_box.d().position.size.width;
|
let in_box_width = in_box.d().position.size.width;
|
||||||
let line_is_empty: bool = self.pending_line.span.len == 0;
|
let line_is_empty: bool = self.pending_line.range.length() == 0;
|
||||||
|
|
||||||
debug!("LineboxScanner: Trying to append box to line %u (box width: %?, remaining width: %?): %s",
|
debug!("LineboxScanner: Trying to append box to line %u (box width: %?, remaining width: %?): %s",
|
||||||
self.line_spans.len(), in_box_width, remaining_width, in_box.debug_str());
|
self.line_spans.len(), in_box_width, remaining_width, in_box.debug_str());
|
||||||
|
@ -459,11 +457,11 @@ impl LineboxScanner {
|
||||||
priv fn push_box_to_line(box: @RenderBox) {
|
priv fn push_box_to_line(box: @RenderBox) {
|
||||||
debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len());
|
debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len());
|
||||||
|
|
||||||
if self.pending_line.span.len == 0 {
|
if self.pending_line.range.length() == 0 {
|
||||||
assert self.new_boxes.len() <= (core::u16::max_value as uint);
|
assert self.new_boxes.len() <= (core::u16::max_value as uint);
|
||||||
self.pending_line.span.start = self.new_boxes.len() as u16;
|
self.pending_line.range.reset(self.new_boxes.len(), 0);
|
||||||
}
|
}
|
||||||
self.pending_line.span.len += 1;
|
self.pending_line.range.extend_by(1);
|
||||||
self.pending_line.width += box.d().position.size.width;
|
self.pending_line.width += box.d().position.size.width;
|
||||||
self.new_boxes.push(box);
|
self.new_boxes.push(box);
|
||||||
}
|
}
|
||||||
|
@ -475,7 +473,7 @@ struct InlineFlowData {
|
||||||
boxes: DVec<@RenderBox>,
|
boxes: DVec<@RenderBox>,
|
||||||
// vec of ranges into boxes that represents line positions.
|
// vec of ranges into boxes that represents line positions.
|
||||||
// these ranges are disjoint, and are the result of inline layout.
|
// these ranges are disjoint, and are the result of inline layout.
|
||||||
lines: DVec<BoxRange>,
|
lines: DVec<Range>,
|
||||||
// vec of ranges into boxes that represent elements. These ranges
|
// vec of ranges into boxes that represent elements. These ranges
|
||||||
// must be well-nested, and are only related to the content of
|
// must be well-nested, and are only related to the content of
|
||||||
// boxes (not lines). Ranges are only kept for non-leaf elements.
|
// boxes (not lines). Ranges are only kept for non-leaf elements.
|
||||||
|
@ -563,7 +561,7 @@ impl FlowContext : InlineLayout {
|
||||||
// coords relative to left baseline
|
// coords relative to left baseline
|
||||||
let mut linebox_bounding_box = au::zero_rect();
|
let mut linebox_bounding_box = au::zero_rect();
|
||||||
let boxes = &self.inline().boxes;
|
let boxes = &self.inline().boxes;
|
||||||
for uint::range(line_span.start as uint, (line_span.start + line_span.len) as uint) |box_i| {
|
for line_span.eachi |box_i| {
|
||||||
let cur_box = boxes[box_i];
|
let cur_box = boxes[box_i];
|
||||||
|
|
||||||
// compute box height.
|
// compute box height.
|
||||||
|
|
|
@ -13,6 +13,8 @@ pub pure fn Range(off: uint, len: uint) -> Range {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub pure fn empty() -> Range { Range(0,0) }
|
||||||
|
|
||||||
pub impl Range {
|
pub impl Range {
|
||||||
pub pure fn begin() -> uint { self.off as uint }
|
pub pure fn begin() -> uint { self.off as uint }
|
||||||
pub pure fn length() -> uint { self.len as uint }
|
pub pure fn length() -> uint { self.len as uint }
|
||||||
|
@ -42,6 +44,8 @@ pub impl Range {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub pure fn empty_mut() -> MutableRange { MutableRange(0,0) }
|
||||||
|
|
||||||
pub struct MutableRange {
|
pub struct MutableRange {
|
||||||
priv mut off: uint,
|
priv mut off: uint,
|
||||||
priv mut len: uint
|
priv mut len: uint
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue