mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Reflow some code and comments in layout/inline.rs
This commit is contained in:
parent
ebdc6f69b1
commit
6f134892da
1 changed files with 53 additions and 32 deletions
|
@ -266,7 +266,9 @@ impl LineBreaker {
|
|||
}
|
||||
|
||||
/// Reflows fragments for the given inline flow.
|
||||
fn scan_for_lines(&mut self, flow: &mut InlineFlow, layout_context: &LayoutContext) {
|
||||
fn scan_for_lines(&mut self,
|
||||
flow: &mut InlineFlow,
|
||||
layout_context: &LayoutContext) {
|
||||
self.reset_scanner();
|
||||
|
||||
// Create our fragment iterator.
|
||||
|
@ -274,10 +276,11 @@ impl LineBreaker {
|
|||
let mut old_fragments = mem::replace(&mut flow.fragments, InlineFragments::new());
|
||||
let old_fragment_iter = old_fragments.fragments.into_iter();
|
||||
|
||||
// TODO(pcwalton): This would likely be better as a list of dirty line indices. That way we
|
||||
// could resynchronize if we discover during reflow that all subsequent fragments must have
|
||||
// the same position as they had in the previous reflow. I don't know how common this case
|
||||
// really is in practice, but it's probably worth handling.
|
||||
// TODO(pcwalton): This would likely be better as a list of dirty line
|
||||
// indices. That way we could resynchronize if we discover during reflow
|
||||
// that all subsequent fragments must have the same position as they had
|
||||
// in the previous reflow. I don't know how common this case really is
|
||||
// in practice, but it's probably worth handling.
|
||||
self.lines = Vec::new();
|
||||
|
||||
// Do the reflow.
|
||||
|
@ -286,9 +289,10 @@ impl LineBreaker {
|
|||
// Perform unicode bidirectional layout.
|
||||
let para_level = flow.base.writing_mode.to_bidi_level();
|
||||
|
||||
// The text within a fragment is at a single bidi embedding level (because we split
|
||||
// fragments on level run boundaries during flow construction), so we can build a level
|
||||
// array with just one entry per fragment.
|
||||
// The text within a fragment is at a single bidi embedding level
|
||||
// (because we split fragments on level run boundaries during flow
|
||||
// construction), so we can build a level array with just one entry per
|
||||
// fragment.
|
||||
let levels: Vec<u8> = self.new_fragments.iter().map(|fragment| match fragment.specific {
|
||||
SpecificFragmentInfo::ScannedText(ref info) => info.run.bidi_level,
|
||||
_ => para_level
|
||||
|
@ -300,7 +304,8 @@ impl LineBreaker {
|
|||
let has_rtl = levels.iter().cloned().any(unicode_bidi::is_rtl);
|
||||
|
||||
if has_rtl {
|
||||
// Compute and store the visual ordering of the fragments within the line.
|
||||
// Compute and store the visual ordering of the fragments within the
|
||||
// line.
|
||||
for line in &mut lines {
|
||||
let range = line.range.begin().to_usize()..line.range.end().to_usize();
|
||||
let runs = unicode_bidi::visual_runs(range, &levels);
|
||||
|
@ -323,7 +328,8 @@ impl LineBreaker {
|
|||
mut old_fragment_iter: I,
|
||||
flow: &'a InlineFlow,
|
||||
layout_context: &LayoutContext)
|
||||
where I: Iterator<Item=Fragment> {
|
||||
where I: Iterator<Item=Fragment>,
|
||||
{
|
||||
loop {
|
||||
// Acquire the next fragment to lay out from the work list or fragment list, as
|
||||
// appropriate.
|
||||
|
@ -355,17 +361,24 @@ impl LineBreaker {
|
|||
/// Acquires a new fragment to lay out from the work list or fragment list as appropriate.
|
||||
/// Note that you probably don't want to call this method directly in order to be incremental-
|
||||
/// reflow-safe; try `next_unbroken_fragment` instead.
|
||||
fn next_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
|
||||
where I: Iterator<Item=Fragment> {
|
||||
fn next_fragment<I>(&mut self,
|
||||
old_fragment_iter: &mut I)
|
||||
-> Option<Fragment>
|
||||
where I: Iterator<Item=Fragment>,
|
||||
{
|
||||
self.work_list.pop_front().or_else(|| old_fragment_iter.next())
|
||||
}
|
||||
|
||||
/// Acquires a new fragment to lay out from the work list or fragment list, merging it with any
|
||||
/// subsequent fragments as appropriate. In effect, what this method does is to return the next
|
||||
/// fragment to lay out, undoing line break operations that any previous reflows may have
|
||||
/// performed. You probably want to be using this method instead of `next_fragment`.
|
||||
fn next_unbroken_fragment<I>(&mut self, old_fragment_iter: &mut I) -> Option<Fragment>
|
||||
where I: Iterator<Item=Fragment> {
|
||||
/// Acquires a new fragment to lay out from the work list or fragment list,
|
||||
/// merging it with any subsequent fragments as appropriate. In effect, what
|
||||
/// this method does is to return the next fragment to lay out, undoing line
|
||||
/// break operations that any previous reflows may have performed. You
|
||||
/// probably want to be using this method instead of `next_fragment`.
|
||||
fn next_unbroken_fragment<I>(&mut self,
|
||||
old_fragment_iter: &mut I)
|
||||
-> Option<Fragment>
|
||||
where I: Iterator<Item=Fragment>,
|
||||
{
|
||||
let mut result = match self.next_fragment(old_fragment_iter) {
|
||||
None => return None,
|
||||
Some(fragment) => fragment,
|
||||
|
@ -536,7 +549,8 @@ impl LineBreaker {
|
|||
|
||||
// Determine initial placement for the fragment if we need to.
|
||||
//
|
||||
// Also, determine whether we can legally break the line before, or inside, this fragment.
|
||||
// Also, determine whether we can legally break the line before, or
|
||||
// inside, this fragment.
|
||||
let fragment_is_line_break_opportunity = if self.pending_line_is_empty() {
|
||||
fragment.strip_leading_whitespace_if_necessary();
|
||||
let (line_bounds, _) = self.initial_line_placement(flow, &fragment, self.cur_b);
|
||||
|
@ -547,15 +561,16 @@ impl LineBreaker {
|
|||
fragment.white_space().allow_wrap()
|
||||
};
|
||||
|
||||
debug!("LineBreaker: trying to append to line {} (fragment size: {:?}, green zone: {:?}): \
|
||||
{:?}",
|
||||
debug!("LineBreaker: trying to append to line {} \
|
||||
(fragment size: {:?}, green zone: {:?}): {:?}",
|
||||
self.lines.len(),
|
||||
fragment.border_box.size,
|
||||
self.pending_line.green_zone,
|
||||
fragment);
|
||||
|
||||
// NB: At this point, if `green_zone.inline < self.pending_line.bounds.size.inline` or
|
||||
// `green_zone.block < self.pending_line.bounds.size.block`, then we committed a line that
|
||||
// NB: At this point, if `green_zone.inline <
|
||||
// self.pending_line.bounds.size.inline` or `green_zone.block <
|
||||
// self.pending_line.bounds.size.block`, then we committed a line that
|
||||
// overlaps with floats.
|
||||
let green_zone = self.pending_line.green_zone;
|
||||
let new_line_metrics = self.pending_line.new_metrics_for_fragment(&fragment,
|
||||
|
@ -1263,7 +1278,8 @@ impl Flow for InlineFlow {
|
|||
fn bubble_inline_sizes(&mut self) {
|
||||
self.update_restyle_damage();
|
||||
|
||||
let _scope = layout_debug_scope!("inline::bubble_inline_sizes {:x}", self.base.debug_id());
|
||||
let _scope = layout_debug_scope!("inline::bubble_inline_sizes {:x}",
|
||||
self.base.debug_id());
|
||||
|
||||
let writing_mode = self.base.writing_mode;
|
||||
for kid in self.base.child_iter_mut() {
|
||||
|
@ -1386,15 +1402,18 @@ impl Flow for InlineFlow {
|
|||
|
||||
/// Calculate and set the block-size of this flow. See CSS 2.1 § 10.6.1.
|
||||
fn assign_block_size(&mut self, layout_context: &LayoutContext) {
|
||||
let _scope = layout_debug_scope!("inline::assign_block_size {:x}", self.base.debug_id());
|
||||
let _scope = layout_debug_scope!("inline::assign_block_size {:x}",
|
||||
self.base.debug_id());
|
||||
|
||||
// Divide the fragments into lines.
|
||||
//
|
||||
// TODO(pcwalton, #226): Get the CSS `line-height` property from the style of the
|
||||
// containing block to determine the minimum line block size.
|
||||
// TODO(pcwalton, #226): Get the CSS `line-height` property from the
|
||||
// style of the containing block to determine the minimum line block
|
||||
// size.
|
||||
//
|
||||
// TODO(pcwalton, #226): Get the CSS `line-height` property from each non-replaced inline
|
||||
// element to determine its block-size for computing the line's own block-size.
|
||||
// TODO(pcwalton, #226): Get the CSS `line-height` property from each
|
||||
// non-replaced inline element to determine its block-size for computing
|
||||
// the line's own block-size.
|
||||
//
|
||||
// TODO(pcwalton): Cache the line scanner?
|
||||
debug!("assign_block_size_inline: floats in: {:?}", self.base.floats);
|
||||
|
@ -1426,7 +1445,8 @@ impl Flow for InlineFlow {
|
|||
// Now, go through each line and lay out the fragments inside.
|
||||
let line_count = self.lines.len();
|
||||
for (line_index, line) in self.lines.iter_mut().enumerate() {
|
||||
// Lay out fragments in the inline direction, and justify them if necessary.
|
||||
// Lay out fragments in the inline direction, and justify them if
|
||||
// necessary.
|
||||
InlineFlow::set_inline_fragment_positions(&mut self.fragments,
|
||||
line,
|
||||
self.base.flags.text_align(),
|
||||
|
@ -1439,8 +1459,9 @@ impl Flow for InlineFlow {
|
|||
&self.minimum_line_metrics,
|
||||
layout_context);
|
||||
|
||||
// This is used to set the block-start position of the next line in the next iteration
|
||||
// of the loop. We're no longer on the first line, so set indentation to zero.
|
||||
// This is used to set the block-start position of the next line in
|
||||
// the next iteration of the loop. We're no longer on the first
|
||||
// line, so set indentation to zero.
|
||||
indentation = Au(0)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue