layout: Implement ordered lists, CSS counters, and quotes per CSS 2.1

§ 12.3-12.5.

Only simple alphabetic and numeric counter styles are supported. (This
is most of them though.)

Although this PR adds a sequential pass to layout, I verified that on
pages that contain a reasonable number of ordered lists (Reddit
`/r/rust`), the time spent in generated content resolution is dwarfed by
the time spent in the parallelizable parts of layout. So I don't expect
this to negatively affect our parallelism expect perhaps in pathological
cases.
This commit is contained in:
Patrick Walton 2015-03-05 12:37:37 -08:00
parent 2df4dd9e09
commit f9cdd05d58
39 changed files with 1704 additions and 537 deletions

View file

@ -12,9 +12,8 @@ use flow::{BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, ScannedTextFragmentInfo};
use fragment::{SpecificFragmentInfo};
use fragment::SplitInfo;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use fragment::{SpecificFragmentInfo, SplitInfo};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
use layout_debug;
use model::IntrinsicISizesContribution;
use text;
@ -789,14 +788,22 @@ pub struct InlineFlow {
impl InlineFlow {
pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
InlineFlow {
let mut flow = InlineFlow {
base: BaseFlow::new(None, writing_mode, ForceNonfloatedFlag::ForceNonfloated),
fragments: fragments,
lines: Vec::new(),
minimum_block_size_above_baseline: Au(0),
minimum_depth_below_baseline: Au(0),
first_line_indentation: Au(0),
};
for fragment in flow.fragments.fragments.iter() {
if fragment.is_generated_content() {
flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT)
}
}
flow
}
/// Returns the distance from the baseline for the logical block-start inline-start corner of
@ -1399,6 +1406,12 @@ impl Flow for InlineFlow {
.translate(stacking_context_position))
}
}
fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) {
for fragment in self.fragments.fragments.iter_mut() {
(*mutator)(fragment)
}
}
}
impl fmt::Debug for InlineFlow {