mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Make text-align: justify
incremental layout safe
This commit is contained in:
parent
da85439093
commit
0f983cd11f
7 changed files with 97 additions and 92 deletions
|
@ -1751,23 +1751,23 @@ impl Fragment {
|
|||
/// Restore any whitespace that was stripped from a text fragment, and recompute inline metrics
|
||||
/// if necessary.
|
||||
pub fn reset_text_range_and_inline_size(&mut self) {
|
||||
match &mut self.specific {
|
||||
&mut SpecificFragmentInfo::ScannedText(ref mut info) => {
|
||||
// FIXME (mbrubeck): Do we need to restore leading too?
|
||||
let range_end = info.range_end_including_stripped_whitespace;
|
||||
if info.range.end() == range_end {
|
||||
return
|
||||
}
|
||||
info.range.extend_to(range_end);
|
||||
info.content_size.inline = info.run.metrics_for_range(&info.range).advance_width;
|
||||
self.border_box.size.inline = info.content_size.inline +
|
||||
self.border_padding.inline_start_end();
|
||||
if let SpecificFragmentInfo::ScannedText(ref mut info) = self.specific {
|
||||
if info.run.extra_word_spacing != Au(0) {
|
||||
Arc::make_mut(&mut info.run).extra_word_spacing = Au(0);
|
||||
}
|
||||
_ => {}
|
||||
|
||||
// FIXME (mbrubeck): Do we need to restore leading too?
|
||||
let range_end = info.range_end_including_stripped_whitespace;
|
||||
if info.range.end() == range_end {
|
||||
return
|
||||
}
|
||||
info.range.extend_to(range_end);
|
||||
info.content_size.inline = info.run.metrics_for_range(&info.range).advance_width;
|
||||
self.border_box.size.inline = info.content_size.inline +
|
||||
self.border_padding.inline_start_end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Assigns replaced inline-size, padding, and margins for this fragment only if it is replaced
|
||||
/// content per CSS 2.1 § 10.3.2.
|
||||
pub fn assign_replaced_inline_size_if_necessary(&mut self, container_inline_size: Au) {
|
||||
|
|
|
@ -961,7 +961,7 @@ impl InlineFlow {
|
|||
}
|
||||
|
||||
// First, calculate the number of expansion opportunities (spaces, normally).
|
||||
let mut expansion_opportunities = 0i32;
|
||||
let mut expansion_opportunities = 0;
|
||||
for fragment_index in line.range.each_index() {
|
||||
let fragment = fragments.get(fragment_index.to_usize());
|
||||
let scanned_text_fragment_info = match fragment.specific {
|
||||
|
@ -971,13 +971,16 @@ impl InlineFlow {
|
|||
let fragment_range = scanned_text_fragment_info.range;
|
||||
|
||||
for slice in scanned_text_fragment_info.run.character_slices_in_range(&fragment_range) {
|
||||
expansion_opportunities += slice.glyphs.space_count_in_range(&slice.range) as i32
|
||||
expansion_opportunities += slice.glyphs.space_count_in_range(&slice.range)
|
||||
}
|
||||
}
|
||||
|
||||
if expansion_opportunities == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Then distribute all the space across the expansion opportunities.
|
||||
let space_per_expansion_opportunity = slack_inline_size.to_f64_px() /
|
||||
(expansion_opportunities as f64);
|
||||
let space_per_expansion_opportunity = slack_inline_size / expansion_opportunities as i32;
|
||||
for fragment_index in line.range.each_index() {
|
||||
let fragment = fragments.get_mut(fragment_index.to_usize());
|
||||
let mut scanned_text_fragment_info = match fragment.specific {
|
||||
|
@ -985,25 +988,8 @@ impl InlineFlow {
|
|||
_ => continue
|
||||
};
|
||||
let fragment_range = scanned_text_fragment_info.range;
|
||||
|
||||
// FIXME(pcwalton): This is an awful lot of uniqueness making. I don't see any easy way
|
||||
// to get rid of it without regressing the performance of the non-justified case,
|
||||
// though.
|
||||
let run = Arc::make_mut(&mut scanned_text_fragment_info.run);
|
||||
{
|
||||
let glyph_runs = Arc::make_mut(&mut run.glyphs);
|
||||
for mut glyph_run in &mut *glyph_runs {
|
||||
let mut range = glyph_run.range.intersect(&fragment_range);
|
||||
if range.is_empty() {
|
||||
continue
|
||||
}
|
||||
range.shift_by(-glyph_run.range.begin());
|
||||
|
||||
let glyph_store = Arc::make_mut(&mut glyph_run.glyph_store);
|
||||
glyph_store.distribute_extra_space_in_range(&range,
|
||||
space_per_expansion_opportunity);
|
||||
}
|
||||
}
|
||||
run.extra_word_spacing = space_per_expansion_opportunity;
|
||||
|
||||
// Recompute the fragment's border box size.
|
||||
let new_inline_size = run.advance_for_range(&fragment_range);
|
||||
|
|
|
@ -393,7 +393,11 @@ impl WebRenderDisplayItemConverter for DisplayItem {
|
|||
|
||||
for slice in item.text_run.natural_word_slices_in_visual_order(&item.range) {
|
||||
for glyph in slice.glyphs.iter_glyphs_for_byte_range(&slice.range) {
|
||||
let glyph_advance = glyph.advance();
|
||||
let glyph_advance = if glyph.char_is_space() {
|
||||
glyph.advance() + item.text_run.extra_word_spacing
|
||||
} else {
|
||||
glyph.advance()
|
||||
};
|
||||
if !slice.glyphs.is_whitespace() {
|
||||
let glyph_offset = glyph.offset().unwrap_or(Point2D::zero());
|
||||
let glyph = webrender_traits::GlyphInstance {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue