mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
Refactor TextRenderBox to handle range and run data and let a RenderBox's style handle font size
This commit is contained in:
parent
5be7bfa14f
commit
5c8c776f0a
3 changed files with 56 additions and 80 deletions
|
@ -10,7 +10,6 @@ use layout::context::LayoutContext;
|
||||||
use layout::debug::DebugMethods;
|
use layout::debug::DebugMethods;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ToGfxColor};
|
use layout::display_list_builder::{DisplayListBuilder, ToGfxColor};
|
||||||
use layout::flow::FlowContext;
|
use layout::flow::FlowContext;
|
||||||
use layout::text::TextBoxData;
|
|
||||||
use layout::text;
|
use layout::text;
|
||||||
|
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
|
@ -20,9 +19,10 @@ use geom::{Point2D, Rect, Size2D};
|
||||||
use gfx::display_list::{DisplayItem, DisplayList};
|
use gfx::display_list::{DisplayItem, DisplayList};
|
||||||
use gfx::font::{FontStyle, FontWeight300};
|
use gfx::font::{FontStyle, FontWeight300};
|
||||||
use gfx::geometry::Au;
|
use gfx::geometry::Au;
|
||||||
|
use gfx::text::text_run::TextRun;
|
||||||
use newcss::color::rgb;
|
use newcss::color::rgb;
|
||||||
use newcss::complete::CompleteStyle;
|
use newcss::complete::CompleteStyle;
|
||||||
use newcss::units::{Cursive, Em, Fantasy, Length, Monospace, Pt, Px, SansSerif, Serif};
|
use newcss::units::{Cursive, Em, Fantasy, Monospace, Pt, Px, SansSerif, Serif};
|
||||||
use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium};
|
use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium};
|
||||||
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily};
|
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily};
|
||||||
use newcss::values::{CSSFontSizeLength, CSSFontStyleItalic, CSSFontStyleNormal};
|
use newcss::values::{CSSFontSizeLength, CSSFontStyleItalic, CSSFontStyleNormal};
|
||||||
|
@ -94,14 +94,13 @@ impl ImageRenderBox {
|
||||||
/// `TextRun` object.
|
/// `TextRun` object.
|
||||||
pub struct TextRenderBox {
|
pub struct TextRenderBox {
|
||||||
base: RenderBoxBase,
|
base: RenderBoxBase,
|
||||||
|
run: @TextRun,
|
||||||
// TODO: Flatten `TextBoxData` into this type.
|
range: Range,
|
||||||
text_data: TextBoxData,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextRenderBox {
|
impl TextRenderBox {
|
||||||
fn teardown(&self) {
|
fn teardown(&self) {
|
||||||
self.text_data.teardown();
|
self.run.teardown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,11 +153,6 @@ pub struct RenderBoxBase {
|
||||||
/// The position of this box relative to its owning flow.
|
/// The position of this box relative to its owning flow.
|
||||||
position: Rect<Au>,
|
position: Rect<Au>,
|
||||||
|
|
||||||
/// The font size.
|
|
||||||
///
|
|
||||||
/// FIXME(pcwalton): Why is this present on non-text-boxes?
|
|
||||||
font_size: Length,
|
|
||||||
|
|
||||||
/// A debug ID.
|
/// A debug ID.
|
||||||
///
|
///
|
||||||
/// TODO(#87) Make this only present in debug builds.
|
/// TODO(#87) Make this only present in debug builds.
|
||||||
|
@ -172,7 +166,6 @@ impl RenderBoxBase {
|
||||||
node: node,
|
node: node,
|
||||||
ctx: flow_context,
|
ctx: flow_context,
|
||||||
position: Au::zero_rect(),
|
position: Au::zero_rect(),
|
||||||
font_size: Px(0.0),
|
|
||||||
id: id,
|
id: id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +254,7 @@ pub impl RenderBox {
|
||||||
self.font_style() == other.font_style() && self.text_decoration() == other.text_decoration()
|
self.font_style() == other.font_style() && self.text_decoration() == other.text_decoration()
|
||||||
},
|
},
|
||||||
(&TextRenderBoxClass(text_box_a), &TextRenderBoxClass(text_box_b)) => {
|
(&TextRenderBoxClass(text_box_a), &TextRenderBoxClass(text_box_b)) => {
|
||||||
managed::ptr_eq(text_box_a.text_data.run, text_box_b.text_data.run)
|
managed::ptr_eq(text_box_a.run, text_box_b.run)
|
||||||
}
|
}
|
||||||
(_, _) => false,
|
(_, _) => false,
|
||||||
}
|
}
|
||||||
|
@ -280,21 +273,21 @@ pub impl RenderBox {
|
||||||
TextRenderBoxClass(text_box) => {
|
TextRenderBoxClass(text_box) => {
|
||||||
let mut pieces_processed_count: uint = 0;
|
let mut pieces_processed_count: uint = 0;
|
||||||
let mut remaining_width: Au = max_width;
|
let mut remaining_width: Au = max_width;
|
||||||
let mut left_range = Range::new(text_box.text_data.range.begin(), 0);
|
let mut left_range = Range::new(text_box.range.begin(), 0);
|
||||||
let mut right_range: Option<Range> = None;
|
let mut right_range: Option<Range> = None;
|
||||||
|
|
||||||
debug!("split_to_width: splitting text box (strlen=%u, range=%?, avail_width=%?)",
|
debug!("split_to_width: splitting text box (strlen=%u, range=%?, avail_width=%?)",
|
||||||
text_box.text_data.run.text.len(),
|
text_box.run.text.len(),
|
||||||
text_box.text_data.range,
|
text_box.range,
|
||||||
max_width);
|
max_width);
|
||||||
|
|
||||||
for text_box.text_data.run.iter_indivisible_pieces_for_range(
|
for text_box.run.iter_indivisible_pieces_for_range(
|
||||||
&text_box.text_data.range) |piece_range| {
|
&text_box.range) |piece_range| {
|
||||||
debug!("split_to_width: considering piece (range=%?, remain_width=%?)",
|
debug!("split_to_width: considering piece (range=%?, remain_width=%?)",
|
||||||
piece_range,
|
piece_range,
|
||||||
remaining_width);
|
remaining_width);
|
||||||
|
|
||||||
let metrics = text_box.text_data.run.metrics_for_range(piece_range);
|
let metrics = text_box.run.metrics_for_range(piece_range);
|
||||||
let advance = metrics.advance_width;
|
let advance = metrics.advance_width;
|
||||||
let should_continue: bool;
|
let should_continue: bool;
|
||||||
|
|
||||||
|
@ -303,9 +296,9 @@ pub impl RenderBox {
|
||||||
|
|
||||||
if starts_line &&
|
if starts_line &&
|
||||||
pieces_processed_count == 0 &&
|
pieces_processed_count == 0 &&
|
||||||
text_box.text_data.run.range_is_trimmable_whitespace(piece_range) {
|
text_box.run.range_is_trimmable_whitespace(piece_range) {
|
||||||
debug!("split_to_width: case=skipping leading trimmable whitespace");
|
debug!("split_to_width: case=skipping leading trimmable whitespace");
|
||||||
left_range.shift_by(piece_range.length() as int);
|
left_range.shift_by(piece_range.length() as int);
|
||||||
} else {
|
} else {
|
||||||
debug!("split_to_width: case=enlarging span");
|
debug!("split_to_width: case=enlarging span");
|
||||||
remaining_width -= advance;
|
remaining_width -= advance;
|
||||||
|
@ -314,24 +307,24 @@ pub impl RenderBox {
|
||||||
} else { // The advance is more than the remaining width.
|
} else { // The advance is more than the remaining width.
|
||||||
should_continue = false;
|
should_continue = false;
|
||||||
|
|
||||||
if text_box.text_data.run.range_is_trimmable_whitespace(piece_range) {
|
if text_box.run.range_is_trimmable_whitespace(piece_range) {
|
||||||
// If there are still things after the trimmable whitespace, create the
|
// If there are still things after the trimmable whitespace, create the
|
||||||
// right chunk.
|
// right chunk.
|
||||||
if piece_range.end() < text_box.text_data.range.end() {
|
if piece_range.end() < text_box.range.end() {
|
||||||
debug!("split_to_width: case=skipping trimmable trailing \
|
debug!("split_to_width: case=skipping trimmable trailing \
|
||||||
whitespace, then split remainder");
|
whitespace, then split remainder");
|
||||||
let right_range_end =
|
let right_range_end =
|
||||||
text_box.text_data.range.end() - piece_range.end();
|
text_box.range.end() - piece_range.end();
|
||||||
right_range = Some(Range::new(piece_range.end(), right_range_end));
|
right_range = Some(Range::new(piece_range.end(), right_range_end));
|
||||||
} else {
|
} else {
|
||||||
debug!("split_to_width: case=skipping trimmable trailing \
|
debug!("split_to_width: case=skipping trimmable trailing \
|
||||||
whitespace");
|
whitespace");
|
||||||
}
|
}
|
||||||
} else if piece_range.begin() < text_box.text_data.range.end() {
|
} else if piece_range.begin() < text_box.range.end() {
|
||||||
// There are still some things left over at the end of the line. Create
|
// There are still some things left over at the end of the line. Create
|
||||||
// the right chunk.
|
// the right chunk.
|
||||||
let right_range_end =
|
let right_range_end =
|
||||||
text_box.text_data.range.end() - piece_range.begin();
|
text_box.range.end() - piece_range.begin();
|
||||||
right_range = Some(Range::new(piece_range.begin(), right_range_end));
|
right_range = Some(Range::new(piece_range.begin(), right_range_end));
|
||||||
debug!("split_to_width: case=splitting remainder with right range=%?",
|
debug!("split_to_width: case=splitting remainder with right range=%?",
|
||||||
right_range);
|
right_range);
|
||||||
|
@ -347,7 +340,7 @@ pub impl RenderBox {
|
||||||
|
|
||||||
let left_box = if left_range.length() > 0 {
|
let left_box = if left_range.length() > 0 {
|
||||||
let new_text_box = @mut text::adapt_textbox_with_range(text_box.base,
|
let new_text_box = @mut text::adapt_textbox_with_range(text_box.base,
|
||||||
text_box.text_data.run,
|
text_box.run,
|
||||||
left_range);
|
left_range);
|
||||||
Some(TextRenderBoxClass(new_text_box))
|
Some(TextRenderBoxClass(new_text_box))
|
||||||
} else {
|
} else {
|
||||||
|
@ -356,11 +349,11 @@ pub impl RenderBox {
|
||||||
|
|
||||||
let right_box = do right_range.map_default(None) |range: &Range| {
|
let right_box = do right_range.map_default(None) |range: &Range| {
|
||||||
let new_text_box = @mut text::adapt_textbox_with_range(text_box.base,
|
let new_text_box = @mut text::adapt_textbox_with_range(text_box.base,
|
||||||
text_box.text_data.run,
|
text_box.run,
|
||||||
*range);
|
*range);
|
||||||
Some(TextRenderBoxClass(new_text_box))
|
Some(TextRenderBoxClass(new_text_box))
|
||||||
};
|
};
|
||||||
|
|
||||||
if pieces_processed_count == 1 || left_box.is_none() {
|
if pieces_processed_count == 1 || left_box.is_none() {
|
||||||
SplitDidNotFit(left_box, right_box)
|
SplitDidNotFit(left_box, right_box)
|
||||||
} else {
|
} else {
|
||||||
|
@ -386,7 +379,7 @@ pub impl RenderBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRenderBoxClass(text_box) => {
|
TextRenderBoxClass(text_box) => {
|
||||||
text_box.text_data.run.min_width_for_range(&text_box.text_data.range)
|
text_box.run.min_width_for_range(&text_box.range)
|
||||||
}
|
}
|
||||||
|
|
||||||
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here.")
|
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here.")
|
||||||
|
@ -414,10 +407,10 @@ pub impl RenderBox {
|
||||||
// report nothing and the parent flow can factor in minimum/preferred widths of any
|
// report nothing and the parent flow can factor in minimum/preferred widths of any
|
||||||
// text runs that it owns.
|
// text runs that it owns.
|
||||||
let mut max_line_width = Au(0);
|
let mut max_line_width = Au(0);
|
||||||
for text_box.text_data.run.iter_natural_lines_for_range(&text_box.text_data.range)
|
for text_box.run.iter_natural_lines_for_range(&text_box.range)
|
||||||
|line_range| {
|
|line_range| {
|
||||||
let mut line_width: Au = Au(0);
|
let mut line_width: Au = Au(0);
|
||||||
for text_box.text_data.run.glyphs.iter_glyphs_for_char_range(line_range)
|
for text_box.run.glyphs.iter_glyphs_for_char_range(line_range)
|
||||||
|_, glyph| {
|
|_, glyph| {
|
||||||
line_width += glyph.advance()
|
line_width += glyph.advance()
|
||||||
}
|
}
|
||||||
|
@ -438,7 +431,7 @@ pub impl RenderBox {
|
||||||
// TODO: This should actually do some computation! See CSS 2.1, Sections 10.3 and 10.4.
|
// TODO: This should actually do some computation! See CSS 2.1, Sections 10.3 and 10.4.
|
||||||
(Au(0), Au(0))
|
(Au(0), Au(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the amount of left and right "fringe" used by this box. This should be based on
|
/// Returns the amount of left and right "fringe" used by this box. This should be based on
|
||||||
/// margins, borders, padding, and width.
|
/// margins, borders, padding, and width.
|
||||||
fn get_used_height(&self) -> (Au, Au) {
|
fn get_used_height(&self) -> (Au, Au) {
|
||||||
|
@ -554,7 +547,7 @@ pub impl RenderBox {
|
||||||
list: &Cell<DisplayList>) {
|
list: &Cell<DisplayList>) {
|
||||||
let box_bounds = self.position();
|
let box_bounds = self.position();
|
||||||
let absolute_box_bounds = box_bounds.translate(offset);
|
let absolute_box_bounds = box_bounds.translate(offset);
|
||||||
debug!("RenderBox::build_display_list at rel=%?, abs=%?: %s",
|
debug!("RenderBox::build_display_list at rel=%?, abs=%?: %s",
|
||||||
box_bounds, absolute_box_bounds, self.debug_str());
|
box_bounds, absolute_box_bounds, self.debug_str());
|
||||||
debug!("RenderBox::build_display_list: dirty=%?, offset=%?", dirty, offset);
|
debug!("RenderBox::build_display_list: dirty=%?, offset=%?", dirty, offset);
|
||||||
|
|
||||||
|
@ -566,7 +559,7 @@ pub impl RenderBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the background to the list, if applicable.
|
// Add the background to the list, if applicable.
|
||||||
self.paint_background_if_applicable(list, &absolute_box_bounds);
|
self.paint_background_if_applicable(list, &absolute_box_bounds);
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here."),
|
UnscannedTextRenderBoxClass(*) => fail!(~"Shouldn't see unscanned boxes here."),
|
||||||
|
@ -577,8 +570,8 @@ pub impl RenderBox {
|
||||||
// FIXME: This should use `with_mut_ref` when that appears.
|
// FIXME: This should use `with_mut_ref` when that appears.
|
||||||
let mut this_list = list.take();
|
let mut this_list = list.take();
|
||||||
this_list.append_item(~DisplayItem::new_Text(&absolute_box_bounds,
|
this_list.append_item(~DisplayItem::new_Text(&absolute_box_bounds,
|
||||||
~text_box.text_data.run.serialize(),
|
~text_box.run.serialize(),
|
||||||
text_box.text_data.range,
|
text_box.range,
|
||||||
color));
|
color));
|
||||||
list.put_back(this_list);
|
list.put_back(this_list);
|
||||||
|
|
||||||
|
@ -586,7 +579,7 @@ pub impl RenderBox {
|
||||||
//
|
//
|
||||||
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
|
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
|
||||||
// should have a real `SERVO_DEBUG` system.
|
// should have a real `SERVO_DEBUG` system.
|
||||||
debug!("%?", {
|
debug!("%?", {
|
||||||
// Compute the text box bounds.
|
// Compute the text box bounds.
|
||||||
//
|
//
|
||||||
// FIXME: This should use `with_mut_ref` when that appears.
|
// FIXME: This should use `with_mut_ref` when that appears.
|
||||||
|
@ -598,8 +591,8 @@ pub impl RenderBox {
|
||||||
// Draw a rectangle representing the baselines.
|
// Draw a rectangle representing the baselines.
|
||||||
//
|
//
|
||||||
// TODO(Issue #221): Create and use a Line display item for the baseline.
|
// TODO(Issue #221): Create and use a Line display item for the baseline.
|
||||||
let ascent = text_box.text_data.run.metrics_for_range(
|
let ascent = text_box.run.metrics_for_range(
|
||||||
&text_box.text_data.range).ascent;
|
&text_box.range).ascent;
|
||||||
let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent),
|
let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent),
|
||||||
Size2D(absolute_box_bounds.size.width, Au(0)));
|
Size2D(absolute_box_bounds.size.width, Au(0)));
|
||||||
|
|
||||||
|
@ -825,9 +818,9 @@ impl DebugMethods for RenderBox {
|
||||||
GenericRenderBoxClass(*) => ~"GenericRenderBox",
|
GenericRenderBoxClass(*) => ~"GenericRenderBox",
|
||||||
ImageRenderBoxClass(*) => ~"ImageRenderBox",
|
ImageRenderBoxClass(*) => ~"ImageRenderBox",
|
||||||
TextRenderBoxClass(text_box) => {
|
TextRenderBoxClass(text_box) => {
|
||||||
fmt!("TextRenderBox(text=%s)", str::substr(text_box.text_data.run.text,
|
fmt!("TextRenderBox(text=%s)", str::substr(text_box.run.text,
|
||||||
text_box.text_data.range.begin(),
|
text_box.range.begin(),
|
||||||
text_box.text_data.range.length()))
|
text_box.range.length()))
|
||||||
}
|
}
|
||||||
UnscannedTextRenderBoxClass(text_box) => {
|
UnscannedTextRenderBoxClass(text_box) => {
|
||||||
fmt!("UnscannedTextRenderBox(%s)", text_box.text)
|
fmt!("UnscannedTextRenderBox(%s)", text_box.text)
|
||||||
|
|
|
@ -229,7 +229,7 @@ impl TextRunScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "clump" is a range of inline flow leaves that can be merged together into a single
|
/// A "clump" is a range of inline flow leaves that can be merged together into a single
|
||||||
/// `RenderBox`. Adjacent text with the same style can be merged, and nothing else can.
|
/// `RenderBox`. Adjacent text with the same style can be merged, and nothing else can.
|
||||||
///
|
///
|
||||||
/// The flow keeps track of the `RenderBox`es contained by all non-leaf DOM nodes. This is
|
/// The flow keeps track of the `RenderBox`es contained by all non-leaf DOM nodes. This is
|
||||||
/// necessary for correct painting order. Since we compress several leaf `RenderBox`es here,
|
/// necessary for correct painting order. Since we compress several leaf `RenderBox`es here,
|
||||||
|
@ -239,7 +239,7 @@ impl TextRunScanner {
|
||||||
/// responsible for swapping out the list. It is not clear to me (pcwalton) that this is still
|
/// responsible for swapping out the list. It is not clear to me (pcwalton) that this is still
|
||||||
/// necessary.
|
/// necessary.
|
||||||
fn flush_clump_to_list(&mut self,
|
fn flush_clump_to_list(&mut self,
|
||||||
ctx: &mut LayoutContext,
|
ctx: &mut LayoutContext,
|
||||||
flow: FlowContext,
|
flow: FlowContext,
|
||||||
out_boxes: &mut ~[RenderBox]) {
|
out_boxes: &mut ~[RenderBox]) {
|
||||||
let inline = &mut *flow.inline();
|
let inline = &mut *flow.inline();
|
||||||
|
@ -265,7 +265,7 @@ impl TextRunScanner {
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
fail!(~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!")
|
fail!(~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!")
|
||||||
}
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
debug!("TextRunScanner: pushing single non-text box in range: %?", self.clump);
|
debug!("TextRunScanner: pushing single non-text box in range: %?", self.clump);
|
||||||
out_boxes.push(in_boxes[self.clump.begin()]);
|
out_boxes.push(in_boxes[self.clump.begin()]);
|
||||||
},
|
},
|
||||||
|
@ -341,7 +341,7 @@ impl TextRunScanner {
|
||||||
debug!("TextRunScanner: pushing box(es) in range: %?", self.clump);
|
debug!("TextRunScanner: pushing box(es) in range: %?", self.clump);
|
||||||
for clump.eachi |i| {
|
for clump.eachi |i| {
|
||||||
let range = new_ranges[i - self.clump.begin()];
|
let range = new_ranges[i - self.clump.begin()];
|
||||||
if range.length() == 0 {
|
if range.length() == 0 {
|
||||||
error!("Elided an `UnscannedTextbox` because it was zero-length after \
|
error!("Elided an `UnscannedTextbox` because it was zero-length after \
|
||||||
compression; %s",
|
compression; %s",
|
||||||
in_boxes[i].debug_str());
|
in_boxes[i].debug_str());
|
||||||
|
@ -355,7 +355,7 @@ impl TextRunScanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // End of match.
|
} // End of match.
|
||||||
|
|
||||||
debug!("--- In boxes: ---");
|
debug!("--- In boxes: ---");
|
||||||
for in_boxes.eachi |i, box| {
|
for in_boxes.eachi |i, box| {
|
||||||
debug!("%u --> %s", i, box.debug_str());
|
debug!("%u --> %s", i, box.debug_str());
|
||||||
|
@ -419,8 +419,8 @@ impl LineboxScanner {
|
||||||
|
|
||||||
pub fn scan_for_lines(&mut self, ctx: &LayoutContext) {
|
pub fn scan_for_lines(&mut self, ctx: &LayoutContext) {
|
||||||
self.reset_scanner();
|
self.reset_scanner();
|
||||||
|
|
||||||
{ // FIXME: manually control borrow length
|
{ // FIXME: manually control borrow length
|
||||||
let inline: &InlineFlowData = self.flow.inline();
|
let inline: &InlineFlowData = self.flow.inline();
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
|
|
||||||
|
@ -455,7 +455,7 @@ impl LineboxScanner {
|
||||||
self.flush_current_line();
|
self.flush_current_line();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // FIXME: scope the borrow
|
{ // FIXME: scope the borrow
|
||||||
let inline: &mut InlineFlowData = self.flow.inline();
|
let inline: &mut InlineFlowData = self.flow.inline();
|
||||||
inline.elems.repair_for_box_changes(inline.boxes, self.new_boxes);
|
inline.elems.repair_for_box_changes(inline.boxes, self.new_boxes);
|
||||||
|
@ -464,7 +464,7 @@ impl LineboxScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn swap_out_results(&mut self) {
|
fn swap_out_results(&mut self) {
|
||||||
debug!("LineboxScanner: Propagating scanned lines[n=%u] to inline flow f%d",
|
debug!("LineboxScanner: Propagating scanned lines[n=%u] to inline flow f%d",
|
||||||
self.line_spans.len(),
|
self.line_spans.len(),
|
||||||
self.flow.id());
|
self.flow.id());
|
||||||
|
|
||||||
|
@ -484,7 +484,7 @@ impl LineboxScanner {
|
||||||
self.line_spans.len(), line_range);
|
self.line_spans.len(), line_range);
|
||||||
|
|
||||||
// Get the text alignment.
|
// Get the text alignment.
|
||||||
// TODO(Issue #222): use 'text-align' property from InlineFlow's
|
// TODO(Issue #222): use 'text-align' property from InlineFlow's
|
||||||
// block container, not from the style of the first box child.
|
// block container, not from the style of the first box child.
|
||||||
let linebox_align;
|
let linebox_align;
|
||||||
if self.pending_line.range.begin() < self.new_boxes.len() {
|
if self.pending_line.range.begin() < self.new_boxes.len() {
|
||||||
|
@ -734,7 +734,7 @@ impl InlineFlowData {
|
||||||
|
|
||||||
let mut scanner = LineboxScanner::new(InlineFlow(self));
|
let mut scanner = LineboxScanner::new(InlineFlow(self));
|
||||||
scanner.scan_for_lines(ctx);
|
scanner.scan_for_lines(ctx);
|
||||||
|
|
||||||
// There are no child contexts, so stop here.
|
// There are no child contexts, so stop here.
|
||||||
|
|
||||||
// TODO(Issue #225): once there are 'inline-block' elements, this won't be
|
// TODO(Issue #225): once there are 'inline-block' elements, this won't be
|
||||||
|
@ -807,8 +807,8 @@ impl InlineFlowData {
|
||||||
// TODO: We can use font metrics directly instead of re-measuring for the
|
// TODO: We can use font metrics directly instead of re-measuring for the
|
||||||
// bounding box.
|
// bounding box.
|
||||||
TextRenderBoxClass(text_box) => {
|
TextRenderBoxClass(text_box) => {
|
||||||
let range = &text_box.text_data.range;
|
let range = &text_box.range;
|
||||||
let run = &text_box.text_data.run;
|
let run = &text_box.run;
|
||||||
let text_bounds = run.metrics_for_range(range).bounding_box;
|
let text_bounds = run.metrics_for_range(range).bounding_box;
|
||||||
text_bounds.translate(&Point2D(text_box.base.position.origin.x, Au(0)))
|
text_bounds.translate(&Point2D(text_box.base.position.origin.x, Au(0)))
|
||||||
},
|
},
|
||||||
|
@ -840,7 +840,7 @@ impl InlineFlowData {
|
||||||
// according to the `vertical-align` property of the containing block.
|
// according to the `vertical-align` property of the containing block.
|
||||||
let halfleading = match cur_box {
|
let halfleading = match cur_box {
|
||||||
TextRenderBoxClass(text_box) => {
|
TextRenderBoxClass(text_box) => {
|
||||||
(text_box.text_data.run.font.metrics.em_size - line_height).scale_by(0.5)
|
(text_box.run.font.metrics.em_size - line_height).scale_by(0.5)
|
||||||
},
|
},
|
||||||
_ => Au(0),
|
_ => Au(0),
|
||||||
};
|
};
|
||||||
|
@ -850,7 +850,7 @@ impl InlineFlowData {
|
||||||
base.position.origin.y = cur_y + halfleading + baseline_offset - height;
|
base.position.origin.y = cur_y + halfleading + baseline_offset - height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_y += Au::max(line_height, linebox_height);
|
cur_y += Au::max(line_height, linebox_height);
|
||||||
} // End of `lines.each` loop.
|
} // End of `lines.each` loop.
|
||||||
|
|
||||||
|
@ -859,7 +859,7 @@ impl InlineFlowData {
|
||||||
|
|
||||||
pub fn build_display_list_inline(&self,
|
pub fn build_display_list_inline(&self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
offset: &Point2D<Au>,
|
offset: &Point2D<Au>,
|
||||||
list: &Cell<DisplayList>) {
|
list: &Cell<DisplayList>) {
|
||||||
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and
|
// TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and
|
||||||
|
|
|
@ -5,28 +5,11 @@
|
||||||
//! Text layout.
|
//! Text layout.
|
||||||
|
|
||||||
use layout::box::{RenderBox, RenderBoxBase, TextRenderBox, UnscannedTextRenderBoxClass};
|
use layout::box::{RenderBox, RenderBoxBase, TextRenderBox, UnscannedTextRenderBoxClass};
|
||||||
|
|
||||||
use gfx::text::text_run::TextRun;
|
use gfx::text::text_run::TextRun;
|
||||||
use servo_util::range::Range;
|
use servo_util::range::Range;
|
||||||
|
|
||||||
pub struct TextBoxData {
|
|
||||||
run: @TextRun,
|
|
||||||
range: Range,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextBoxData {
|
|
||||||
pub fn new(run: @TextRun, range: Range) -> TextBoxData {
|
|
||||||
TextBoxData {
|
|
||||||
run: run,
|
|
||||||
range: range,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn teardown(&self) {
|
|
||||||
self.run.teardown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// Creates a TextRenderBox from a range and a text run.
|
||||||
pub fn adapt_textbox_with_range(mut base: RenderBoxBase, run: @TextRun, range: Range)
|
pub fn adapt_textbox_with_range(mut base: RenderBoxBase, run: @TextRun, range: Range)
|
||||||
-> TextRenderBox {
|
-> TextRenderBox {
|
||||||
assert!(range.begin() < run.char_len());
|
assert!(range.begin() < run.char_len());
|
||||||
|
@ -38,14 +21,14 @@ pub fn adapt_textbox_with_range(mut base: RenderBoxBase, run: @TextRun, range: R
|
||||||
range.begin(),
|
range.begin(),
|
||||||
range.length(),
|
range.length(),
|
||||||
run.text);
|
run.text);
|
||||||
let new_text_data = TextBoxData::new(run, range);
|
|
||||||
let metrics = run.metrics_for_range(&range);
|
|
||||||
|
|
||||||
|
let metrics = run.metrics_for_range(&range);
|
||||||
base.position.size = metrics.bounding_box.size;
|
base.position.size = metrics.bounding_box.size;
|
||||||
|
|
||||||
TextRenderBox {
|
TextRenderBox {
|
||||||
base: base,
|
base: base,
|
||||||
text_data: new_text_data,
|
run: run,
|
||||||
|
range: range,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue