Swap RenderBox and RenderBoxData, making RenderBox variants each hold

the common struct as first field. Add a d() accessor for the common
struct data. Other miscellaneous fixes.
This commit is contained in:
Brian J. Burg 2012-09-26 16:14:15 -07:00
parent b9b3895a8a
commit e89d2fa782
10 changed files with 195 additions and 149 deletions

View file

@ -65,11 +65,11 @@ impl Node : cmp::Eq {
impl Node : DebugMethods {
/* Dumps the subtree rooted at this node, for debugging. */
fn dump() {
fn dump(&self) {
self.dump_indent(0u);
}
/* Dumps the node tree, for debugging, with indentation. */
fn dump_indent(indent: uint) {
fn dump_indent(&self, indent: uint) {
let mut s = ~"";
for uint::range(0u, indent) |_i| {
s += ~" ";
@ -78,12 +78,12 @@ impl Node : DebugMethods {
s += self.debug_str();
debug!("%s", s);
for NodeTree.each_child(self) |kid| {
for NodeTree.each_child(*self) |kid| {
kid.dump_indent(indent + 1u)
}
}
fn debug_str() -> ~str {
fn debug_str(&self) -> ~str {
do self.read |n| { fmt!("%?", n.kind) }
}
}

View file

@ -33,7 +33,7 @@ trait BlockLayout {
c: &Point2D<au>, d: &dl::DisplayList);
}
impl @FlowContext : BlockLayout {
impl FlowContext : BlockLayout {
pure fn starts_block_flow() -> bool {
match self.kind {
@ -85,7 +85,7 @@ impl @FlowContext : BlockLayout {
let mut pref_width = au(0);
/* find max width from child block contexts */
for FlowTree.each_child(self) |child_ctx| {
for FlowTree.each_child(@self) |child_ctx| {
assert child_ctx.starts_block_flow() || child_ctx.starts_inline_flow();
min_width = au::max(min_width, child_ctx.data.min_width);
@ -120,12 +120,12 @@ impl @FlowContext : BlockLayout {
/* Let the box consume some width. It will return the amount remaining
for its children. */
do self.with_block_box |box| {
box.data.position.size.width = remaining_width;
box.d().position.size.width = remaining_width;
let (left_used, right_used) = box.get_used_width();
remaining_width = remaining_width.sub(left_used.add(right_used));
}
for FlowTree.each_child(self) |child_ctx| {
for FlowTree.each_child(@self) |child_ctx| {
assert child_ctx.starts_block_flow() || child_ctx.starts_inline_flow();
child_ctx.data.position.origin.x = left_used;
child_ctx.data.position.size.width = remaining_width;
@ -137,7 +137,7 @@ impl @FlowContext : BlockLayout {
let mut cur_y = au(0);
for FlowTree.each_child(self) |child_ctx| {
for FlowTree.each_child(@self) |child_ctx| {
child_ctx.data.position.origin.y = cur_y;
cur_y = cur_y.add(child_ctx.data.position.size.height);
}
@ -148,8 +148,8 @@ impl @FlowContext : BlockLayout {
let _used_bot = au(0);
do self.with_block_box |box| {
box.data.position.origin.y = au(0);
box.data.position.size.height = cur_y;
box.d().position.origin.y = au(0);
box.d().position.size.height = cur_y;
let (_used_top, _used_bot) = box.get_used_height();
}
}
@ -167,7 +167,7 @@ impl @FlowContext : BlockLayout {
// TODO: handle any out-of-flow elements
// go deeper into the flow tree
for FlowTree.each_child(self) |child| {
for FlowTree.each_child(@self) |child| {
self.build_display_list_for_child(builder, child, dirty, offset, list)
}
}

View file

@ -18,7 +18,7 @@ use geom::size::Size2D;
use geom::point::Point2D;
use image::{Image, ImageHolder};
use layout::context::LayoutContext;
use layout::debug::DebugMethods;
use layout::debug::BoxedDebugMethods;
use layout::flow::FlowContext;
use layout::text::TextBoxData;
use servo_text::text_run::TextRun;
@ -68,27 +68,8 @@ padding, backgrounds. It is analogous to a CSS nonreplaced content box.
It also holds data specific to different box types, such as text.
*/
struct BoxLayoutData {
mut position: Rect<au>,
mut font_size: Length,
}
/* TODO: this should eventually be just 'position', and
merged into the base RenderBox struct */
fn BoxLayoutData() -> BoxLayoutData {
BoxLayoutData {
position : au::zero_rect(),
font_size : Px(0.0),
}
}
enum BoxData {
GenericBox,
ImageBox(ImageHolder),
TextBox(TextBoxData)
}
struct RenderBox {
struct RenderBoxData {
/* references to children, parent inline flow boxes */
tree : tree::Tree<@RenderBox>,
/* originating DOM node */
@ -96,30 +77,51 @@ struct RenderBox {
/* reference to containing flow context, which this box
participates in */
ctx : @FlowContext,
/* results of flow computation */
data : BoxLayoutData,
/* kind tag and kind-specific data */
kind : BoxData,
/* position of this box relative to owning flow */
mut position : Rect<au>,
font_size : Length,
/* TODO (Issue #87): debug only */
mut id: int
}
fn RenderBox(id: int, node: Node, ctx: @FlowContext, kind: BoxData) -> RenderBox {
RenderBox {
enum RenderBoxType {
RenderBox_Generic,
RenderBox_Image,
RenderBox_Text
}
enum RenderBox {
GenericBox(RenderBoxData),
ImageBox(RenderBoxData, ImageHolder),
TextBox(RenderBoxData, TextBoxData)
}
impl RenderBox {
pure fn d(&self) -> &self/RenderBoxData {
match *self {
GenericBox(ref d) => d,
ImageBox(ref d, _) => d,
TextBox(ref d, _) => d
}
}
}
fn RenderBoxData(node: Node, ctx: @FlowContext, id: int) -> RenderBoxData {
RenderBoxData {
/* will be set if box is parented */
tree : tree::empty(),
node : node,
ctx : ctx,
data : BoxLayoutData(),
kind : kind,
mut ctx : ctx,
mut position : au::zero_rect(),
font_size: Px(0.0),
id : id
}
}
impl @RenderBox {
impl RenderBox {
pure fn is_replaced() -> bool {
match self.kind {
ImageBox(*) => true, // TODO: form elements, etc
match self {
ImageBox(*) => true, // TODO: form elements, etc
_ => false
}
}
@ -129,35 +131,35 @@ impl @RenderBox {
* holder.get_image()
*/
fn get_min_width() -> au {
match self.kind {
match self {
// TODO: this should account for min/pref widths of the
// box element in isolation. That includes
// border/margin/padding but not child widths. The block
// FlowContext will combine the width of this element and
// that of its children to arrive at the context width.
GenericBox => au(0),
GenericBox(*) => au(0),
// TODO: consult CSS 'width', margin, border.
// TODO: If image isn't available, consult 'width'.
ImageBox(i) => au::from_px(i.get_size().get_default(Size2D(0,0)).width),
TextBox(d) => d.runs.foldl(au(0), |sum, run| {
ImageBox(_,i) => au::from_px(i.get_size().get_default(Size2D(0,0)).width),
TextBox(_,d) => d.runs.foldl(au(0), |sum, run| {
au::max(sum, run.min_break_width())
})
}
}
fn get_pref_width() -> au {
match self.kind {
match self {
// TODO: this should account for min/pref widths of the
// box element in isolation. That includes
// border/margin/padding but not child widths. The block
// FlowContext will combine the width of this element and
// that of its children to arrive at the context width.
GenericBox => au(0),
ImageBox(i) => au::from_px(i.get_size().get_default(Size2D(0,0)).width),
GenericBox(*) => au(0),
ImageBox(_,i) => au::from_px(i.get_size().get_default(Size2D(0,0)).width),
// TODO: account for line breaks, etc. The run should know
// how to compute its own min and pref widths, and should
// probably cache them.
TextBox(d) => d.runs.foldl(au(0), |sum, run| {
TextBox(_,d) => d.runs.foldl(au(0), |sum, run| {
au::max(sum, run.size().width)
})
}
@ -184,21 +186,21 @@ impl @RenderBox {
/* The box formed by the content edge, as defined in CSS 2.1 Section 8.1.
Coordinates are relative to the owning flow. */
pure fn content_box() -> Rect<au> {
match self.kind {
ImageBox(i) => {
match self {
ImageBox(_,i) => {
let size = i.size();
Rect {
origin: copy self.data.position.origin,
origin: copy self.d().position.origin,
size: Size2D(au::from_px(size.width),
au::from_px(size.height))
}
},
GenericBox(*) => {
copy self.data.position
copy self.d().position
/* FIXME: The following hits an ICE for whatever reason
let origin = self.data.position.origin;
let size = self.data.position.size;
let origin = self.d().position.origin;
let size = self.d().position.size;
let (offset_left, offset_right) = self.get_used_width();
let (offset_top, offset_bottom) = self.get_used_height();
@ -209,7 +211,7 @@ impl @RenderBox {
}*/
},
TextBox(*) => {
copy self.data.position
copy self.d().position
}
}
}
@ -241,15 +243,15 @@ impl @RenderBox {
*/
fn build_display_list(_builder: &dl::DisplayListBuilder, dirty: &Rect<au>,
offset: &Point2D<au>, list: &dl::DisplayList) {
if !self.data.position.intersects(dirty) {
if !self.d().position.intersects(dirty) {
return;
}
let bounds : Rect<au> = Rect(self.data.position.origin.add(offset),
copy self.data.position.size);
let bounds : Rect<au> = Rect(self.d().position.origin.add(offset),
copy self.d().position.size);
match self.kind {
TextBox(d) => {
match self {
TextBox(_,d) => {
let mut runs = d.runs;
// TODO: don't paint background for text boxes
list.push(~dl::SolidColor(bounds, 255u8, 255u8, 255u8));
@ -271,13 +273,13 @@ impl @RenderBox {
},
// TODO: items for background, border, outline
GenericBox(*) => { },
ImageBox(i) => {
ImageBox(_,i) => {
match i.get_image() {
Some(image) => list.push(~dl::Image(bounds, image)),
/* No image data at all? Okay, add some fallback content instead. */
None => {
// TODO: shouldn't need to unbox CSSValue by now
let boxed_color = self.node.style().background_color;
let boxed_color = self.d().node.style().background_color;
let color = match boxed_color {
Specified(BgColor(c)) => c,
Specified(BgColorTransparent) | _ => util::color::rgba(0,0,0,0.0)
@ -290,6 +292,10 @@ impl @RenderBox {
}
}
trait ImageBoxMethods {
}
/**
* The tree holding render box relations. These are only defined for
* nested CSS boxes that are nested in an otherwise inline flow
@ -303,7 +309,7 @@ impl RenderBoxTree : tree::ReadMethods<@RenderBox> {
}
fn with_tree_fields<R>(&&b: @RenderBox, f: fn(tree::Tree<@RenderBox>) -> R) -> R {
f(b.tree)
f(b.d().tree)
}
}
@ -314,17 +320,17 @@ impl RenderBoxTree : tree::WriteMethods<@RenderBox> {
}
fn with_tree_fields<R>(&&b: @RenderBox, f: fn(tree::Tree<@RenderBox>) -> R) -> R {
f(b.tree)
f(b.d().tree)
}
}
impl @RenderBox : DebugMethods {
fn dump() {
impl RenderBox : BoxedDebugMethods {
fn dump(@self) {
self.dump_indent(0u);
}
/* Dumps the node tree, for debugging, with indentation. */
fn dump_indent(indent: uint) {
fn dump_indent(@self, indent: uint) {
let mut s = ~"";
for uint::range(0u, indent) |_i| {
s += ~" ";
@ -338,11 +344,11 @@ impl @RenderBox : DebugMethods {
}
}
fn debug_str() -> ~str {
let repr = match self.kind {
GenericBox(*) => ~"GenericBox",
ImageBox(*) => ~"ImageBox",
TextBox(d) => {
fn debug_str(@self) -> ~str {
let repr = match self {
@GenericBox(*) => ~"GenericBox",
@ImageBox(*) => ~"ImageBox",
@TextBox(_,d) => {
let mut s = d.runs.foldl(~"TextBox(runs=", |s, run| {
fmt!("%s \"%s\"", s, run.text)
});
@ -350,7 +356,7 @@ impl @RenderBox : DebugMethods {
}
};
fmt!("box b%?: %?", self.id, repr)
fmt!("box b%?: %?", self.d().id, repr)
}
}

View file

@ -8,7 +8,7 @@ use dom::element::*;
use dom::node::{Comment, Doctype, Element, Text, Node, NodeTree, LayoutData};
use image::holder::ImageHolder;
use layout::flow::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree};
use layout::box::{RenderBox, BoxData, GenericBox, ImageBox, TextBox, RenderBoxTree};
use layout::box::*;
use layout::block::BlockFlowData;
use layout::context::LayoutContext;
use layout::inline::InlineFlowData;
@ -58,21 +58,21 @@ impl LayoutTreeBuilder {
v => v
};
// first, create the proper box kind, based on node characteristics
let box_data = self.create_box_data(layout_ctx, cur_node, simulated_display);
// first, determine the box type, based on node characteristics
let box_type = self.decide_box_type(cur_node, simulated_display);
// then, figure out its proper context, possibly reorganizing.
let next_ctx: @FlowContext = match box_data {
let next_ctx: @FlowContext = match box_type {
/* Text box is always an inline flow. create implicit inline
flow ctx if we aren't inside one already. */
TextBox(*) => {
RenderBox_Text => {
if (parent_ctx.starts_inline_flow()) {
parent_ctx
} else {
self.make_ctx(InlineFlow(InlineFlowData()), tree::empty())
}
},
ImageBox(*) | GenericBox => {
RenderBox_Image | RenderBox_Generic => {
match simulated_display {
DisplayInline | DisplayInlineBlock => {
/* if inline, try to put into inline context,
@ -98,7 +98,7 @@ impl LayoutTreeBuilder {
do cur_node.aux |data| { data.flow = Some(next_ctx) }
// make box, add box to any context-specific list.
let mut new_box = self.make_box(cur_node, parent_ctx, box_data);
let mut new_box = self.make_box(layout_ctx, box_type, cur_node, parent_ctx);
debug!("Assign ^box to flow: %?", next_ctx.debug_str());
match next_ctx.kind {
@ -109,7 +109,7 @@ impl LayoutTreeBuilder {
let parent = parent_box.get();
// connect the box to its parent box
debug!("In inline flow f%?, set child b%? of parent b%?", next_ctx.id, parent.id, new_box.id);
debug!("In inline flow f%?, set child b%? of parent b%?", next_ctx.id, parent.d().id, new_box.d().id);
RenderBoxTree.add_child(parent, new_box);
}
}
@ -118,7 +118,7 @@ impl LayoutTreeBuilder {
};
if (!next_ctx.eq(&parent_ctx)) {
if !core::box::ptr_eq(next_ctx, parent_ctx) {
debug!("Adding child flow f%? of f%?", parent_ctx.id, next_ctx.id);
FlowTree.add_child(parent_ctx, next_ctx);
}
@ -188,39 +188,79 @@ impl LayoutTreeBuilder {
ret
}
fn make_box(node : Node, ctx: @FlowContext, data: BoxData) -> @RenderBox {
let ret = @RenderBox(self.next_box_id(), node, ctx, data);
/**
disambiguate between different methods here instead of inlining, since each
case has very different complexity
*/
fn make_box(layout_ctx: &LayoutContext, ty: RenderBoxType, node: Node, ctx: @FlowContext) -> @RenderBox {
let ret = match ty {
RenderBox_Generic => self.make_generic_box(layout_ctx, node, ctx),
RenderBox_Text => self.make_text_box(layout_ctx, node, ctx),
RenderBox_Image => self.make_image_box(layout_ctx, node, ctx),
};
debug!("Created box: %s", ret.debug_str());
ret
}
/* Based on the DOM node type, create a specific type of box */
fn create_box_data(layout_ctx: &LayoutContext, node: Node, display: CSSDisplay) -> BoxData {
// TODO: handle more types of nodes.
fn make_generic_box(_layout_ctx: &LayoutContext, node: Node, ctx: @FlowContext) -> @RenderBox {
@GenericBox(RenderBoxData(node, ctx, self.next_box_id()))
}
fn make_image_box(layout_ctx: &LayoutContext, node: Node, ctx: @FlowContext) -> @RenderBox {
do node.read |n| {
match n.kind {
~Element(ed) => match ed.kind {
~HTMLImageElement(d) => {
// TODO: this could be written as a pattern guard, but it triggers
// an ICE (mozilla/rust issue #3601)
if d.image.is_some() {
let holder = ImageHolder(&d.image.get(),
layout_ctx.image_cache,
copy layout_ctx.reflow_cb);
@ImageBox(RenderBoxData(node, ctx, self.next_box_id()), holder)
} else {
info!("Tried to make image box, but couldn't find image. Made generic box instead.");
self.make_generic_box(layout_ctx, node, ctx)
}
},
_ => fail ~"WAT error: why couldn't we make an image box?"
},
_ => fail ~"WAT error: why couldn't we make an image box?"
}
}
}
fn make_text_box(layout_ctx: &LayoutContext, node: Node, ctx: @FlowContext) -> @RenderBox {
do node.read |n| {
match n.kind {
~Doctype(*) | ~Comment(*) => fail ~"Hey, doctypes and comments shouldn't get here! They are display:none!",
~Text(string) => {
// TODO: clean this up. Fonts should not be created here.
let font = layout_ctx.font_cache.get_test_font();
let run = TextRun(font, string);
TextBox(TextBoxData(copy string, ~[move run]))
}
@TextBox(RenderBoxData(node, ctx, self.next_box_id()),
TextBoxData(copy string, ~[move run]))
},
_ => fail ~"WAT error: why couldn't we make a text box?"
}
}
}
fn decide_box_type(node: Node, display: CSSDisplay) -> RenderBoxType {
do node.read |n| {
match n.kind {
~Doctype(*) | ~Comment(*) => fail ~"Hey, doctypes and comments shouldn't get here! They are display:none!",
~Text(*) => RenderBox_Text,
~Element(element) => {
match (element.kind, display) {
(~HTMLImageElement(d), _) if d.image.is_some() => {
let holder = ImageHolder(&d.image.get(),
layout_ctx.image_cache,
copy layout_ctx.reflow_cb);
ImageBox(holder)
},
(~HTMLImageElement(d), _) if d.image.is_some() => RenderBox_Image,
// (_, Specified(_)) => GenericBox,
(_, _) => GenericBox // TODO: replace this with the commented lines
(_, _) => RenderBox_Generic // TODO: replace this with the commented lines
// (_, _) => fail ~"Can't create box for Node with non-specified 'display' type"
}
}
}
}
}
}
}

View file

@ -1,5 +1,11 @@
trait DebugMethods {
fn dump();
fn dump_indent(ident: uint);
fn debug_str() -> ~str;
trait BoxedDebugMethods {
fn dump(@self);
fn dump_indent(@self, ident: uint);
fn debug_str(@self) -> ~str;
}
trait DebugMethods {
fn dump(&self);
fn dump_indent(&self, ident: uint);
fn debug_str(&self) -> ~str;
}

View file

@ -38,7 +38,7 @@ trait FlowDisplayListBuilderMethods {
c: &Rect<au>, d: &Point2D<au>, e: &dl::DisplayList);
}
impl @FlowContext: FlowDisplayListBuilderMethods {
impl FlowContext: FlowDisplayListBuilderMethods {
fn build_display_list(builder: &DisplayListBuilder, dirty: &Rect<au>, list: &dl::DisplayList) {
let zero = au::zero_point();

View file

@ -8,7 +8,7 @@ use geom::point::Point2D;
use layout::block::BlockFlowData;
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::debug::DebugMethods;
use layout::debug::BoxedDebugMethods;
use layout::inline::InlineFlowData;
use layout::root::RootFlowData;
use util::tree;
@ -92,14 +92,8 @@ fn FlowContext(id: int, kind: FlowContextData, tree: tree::Tree<@FlowContext>) -
}
}
impl @FlowContext : cmp::Eq {
pure fn eq(other: &@FlowContext) -> bool { core::box::ptr_eq(self, *other) }
pure fn ne(other: &@FlowContext) -> bool { !core::box::ptr_eq(self, *other) }
}
/* Flow context disambiguation methods: the verbose alternative to virtual methods */
impl @FlowContext {
impl FlowContext {
fn bubble_widths(ctx: &LayoutContext) {
match self.kind {
BlockFlow(*) => self.bubble_widths_block(ctx),
@ -139,19 +133,19 @@ impl @FlowContext {
}
// Actual methods that do not require much flow-specific logic
impl @FlowContext {
impl FlowContext {
pure fn foldl_boxes_for_node<B: Copy>(node: Node, seed: B, blk: pure fn&(B,@RenderBox) -> B) -> B {
match self.kind {
RootFlow(d) => match d.box {
Some(box) if box.node == node => { blk(seed, box) },
Some(box) if box.d().node == node => { blk(seed, box) },
_ => seed
},
BlockFlow(d) => match d.box {
Some(box) if box.node == node => { blk(seed, box) },
Some(box) if box.d().node == node => { blk(seed, box) },
_ => seed
},
InlineFlow(d) => do d.boxes.foldl(seed) |acc, box| {
if box.node == node { blk(acc, box) }
if box.d().node == node { blk(acc, box) }
else { acc }
},
_ => fail fmt!("Don't know how to iterate node's RenderBoxes for %?", self.kind)
@ -161,16 +155,16 @@ impl @FlowContext {
pure fn iter_boxes_for_node<T>(node: Node, cb: pure fn&(@RenderBox) -> T) {
match self.kind {
RootFlow(d) => match d.box {
Some(box) if box.node == node => { cb(box); },
Some(box) if box.d().node == node => { cb(box); },
_ => {}
},
BlockFlow(d) => match d.box {
Some(box) if box.node == node => { cb(box); },
Some(box) if box.d().node == node => { cb(box); },
_ => {}
},
InlineFlow(d) => {
for d.boxes.each |box| {
if box.node == node { cb(*box); }
if box.d().node == node { cb(*box); }
}
},
_ => fail fmt!("Don't know how to iterate node's RenderBoxes for %?", self.kind)
@ -204,13 +198,13 @@ impl FlowTree : tree::WriteMethods<@FlowContext> {
}
impl @FlowContext : DebugMethods {
fn dump() {
impl FlowContext : BoxedDebugMethods {
fn dump(@self) {
self.dump_indent(0u);
}
/** Dumps the flow tree, for debugging, with indentation. */
fn dump_indent(indent: uint) {
fn dump_indent(@self, indent: uint) {
let mut s = ~"|";
for uint::range(0u, indent) |_i| {
s += ~"---- ";
@ -225,17 +219,17 @@ impl @FlowContext : DebugMethods {
}
/* TODO: we need a string builder. This is horribly inefficient */
fn debug_str() -> ~str {
fn debug_str(@self) -> ~str {
let repr = match self.kind {
InlineFlow(d) => {
let mut s = d.boxes.foldl(~"InlineFlow(children=", |s, box| {
fmt!("%s %?", s, box.id)
fmt!("%s %?", s, box.d().id)
});
s += ~")"; s
},
BlockFlow(d) => {
match d.box {
Some(_b) => fmt!("BlockFlow(box=b%?)", d.box.get().id),
Some(_b) => fmt!("BlockFlow(box=b%?)", d.box.get().d().id),
None => ~"BlockFlow",
}
},

View file

@ -57,7 +57,7 @@ trait InlineLayout {
fn build_display_list_inline(a: &dl::DisplayListBuilder, b: &Rect<au>, c: &Point2D<au>, d: &dl::DisplayList);
}
impl @FlowContext : InlineLayout {
impl FlowContext : InlineLayout {
pure fn starts_inline_flow() -> bool { match self.kind { InlineFlow(*) => true, _ => false } }
pure fn access_inline<T>(cb: fn(&&InlineFlowData) -> T) -> T {
@ -110,27 +110,27 @@ impl @FlowContext : InlineLayout {
/* hack: until text box splitting is hoisted into this
function, force "reflow" on TextBoxes. */
match box.kind {
TextBox(*) => box.reflow_text(ctx),
match *box {
@TextBox(*) => box.reflow_text(ctx),
_ => {}
}
box.data.position.size.width = match box.kind {
ImageBox(img) => au::from_px(img.get_size().get_default(Size2D(0,0)).width),
TextBox(d) => d.runs[0].size().width,
box.d().position.size.width = match *box {
@ImageBox(_,img) => au::from_px(img.get_size().get_default(Size2D(0,0)).width),
@TextBox(_,d) => d.runs[0].size().width,
// TODO: this should be set to the extents of its children
GenericBox(*) => au(0)
@GenericBox(*) => au(0)
};
box.data.position.size.height = match box.kind {
ImageBox(img) => au::from_px(img.get_size().get_default(Size2D(0,0)).height),
TextBox(d) => d.runs[0].size().height,
box.d().position.size.height = match *box {
@ImageBox(_,img) => au::from_px(img.get_size().get_default(Size2D(0,0)).height),
@TextBox(_,d) => d.runs[0].size().height,
// TODO: this should be set to the extents of its children
GenericBox(*) => au(0)
@GenericBox(*) => au(0)
};
box.data.position.origin = Point2D(au(0), cur_y);
cur_y = cur_y.add(au::max(line_height, box.data.position.size.height));
box.d().position.origin = Point2D(au(0), cur_y);
cur_y = cur_y.add(au::max(line_height, box.d().position.size.height));
} // for boxes.each |box|
}

View file

@ -30,7 +30,7 @@ trait RootLayout {
fn build_display_list_root(a: &dl::DisplayListBuilder, b: &Rect<au>, c: &Point2D<au>, d: &dl::DisplayList);
}
impl @FlowContext : RootLayout {
impl FlowContext : RootLayout {
pure fn starts_root_flow() -> bool {
match self.kind {

View file

@ -27,8 +27,8 @@ trait TextLayout {
#[doc="The main reflow routine for text layout."]
impl @RenderBox : TextLayout {
fn reflow_text(ctx: &LayoutContext) {
let d = match self.kind {
TextBox(d) => { d }
let d = match self {
@TextBox(_,d) => { d }
_ => { fail ~"expected text box in reflow_text!" }
};
@ -73,7 +73,7 @@ impl @RenderBox : TextLayout {
let total_height = au(*current.size().height * line_count);
lines.push(move current);
self.data.position.size = Size2D(max_width, total_height);
self.d().position.size = Size2D(max_width, total_height);
d.runs = move dvec::unwrap(lines);
}
}