mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Thread RenderContext and LayoutContext throughout computations needing task assets, such as document URL, font cache, or image cache.
This commit is contained in:
parent
bcdc2ac597
commit
972791bb9f
18 changed files with 221 additions and 212 deletions
|
@ -1,7 +1,8 @@
|
|||
#[doc="Applies the appropriate CSS style to boxes."]
|
||||
|
||||
use au = gfx::geometry;
|
||||
use layout::base::{Box, SpecifiedStyle};
|
||||
use layout::base::{Box, SpecifiedStyle, BoxTree};
|
||||
use layout::context::LayoutContext;
|
||||
use layout::traverse_parallel::top_down_traversal;
|
||||
use image::ImageHolder;
|
||||
use resource::image_cache_task::ImageCacheTask;
|
||||
|
@ -32,35 +33,29 @@ impl CSSValue<CSSFontSize> : ResolveMethods<CSSFontSize> {
|
|||
|
||||
struct StyleApplicator {
|
||||
box: @Box,
|
||||
doc_url: &Url,
|
||||
image_cache_task: ImageCacheTask,
|
||||
reflow: fn~(),
|
||||
}
|
||||
|
||||
// TODO: normalize this into a normal preorder tree traversal function
|
||||
fn apply_style(box: @Box, doc_url: &Url, image_cache_task: ImageCacheTask, reflow: fn~()) {
|
||||
fn apply_style(layout_ctx: &LayoutContext, box: @Box, reflow: fn~()) {
|
||||
let applicator = StyleApplicator {
|
||||
box: box,
|
||||
doc_url: doc_url,
|
||||
image_cache_task: image_cache_task,
|
||||
reflow: reflow
|
||||
};
|
||||
|
||||
applicator.apply_css_style();
|
||||
applicator.apply_css_style(layout_ctx);
|
||||
}
|
||||
|
||||
// TODO: this is misleadingly-named. It is actually trying to resolve CSS 'inherit' values.
|
||||
|
||||
#[doc="A wrapper around a set of functions that can be applied as a top-down traversal of layout
|
||||
boxes."]
|
||||
fn inheritance_wrapper(box : @Box, doc_url: &Url, image_cache_task: ImageCacheTask, reflow: fn~()) {
|
||||
fn inheritance_wrapper(layout_ctx: &LayoutContext, box : @Box, reflow: fn~()) {
|
||||
let applicator = StyleApplicator {
|
||||
box: box,
|
||||
doc_url: doc_url,
|
||||
image_cache_task: image_cache_task,
|
||||
reflow: reflow
|
||||
};
|
||||
applicator.apply_style();
|
||||
applicator.apply_style(layout_ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -104,12 +99,11 @@ fn resolve_width(box : @Box) {
|
|||
}*/
|
||||
|
||||
impl StyleApplicator {
|
||||
fn apply_css_style() {
|
||||
let doc_url = copy *self.doc_url;
|
||||
let image_cache_task = self.image_cache_task;
|
||||
fn apply_css_style(layout_ctx: &LayoutContext) {
|
||||
let reflow = copy self.reflow;
|
||||
do top_down_traversal(self.box) |box, move doc_url| {
|
||||
inheritance_wrapper(box, &doc_url, image_cache_task, reflow);
|
||||
|
||||
do BoxTree.each_child(self.box) |child| {
|
||||
inheritance_wrapper(layout_ctx, child, reflow); true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +114,7 @@ impl StyleApplicator {
|
|||
value for the given type of element and use that instead.
|
||||
|
||||
"]
|
||||
fn apply_style() {
|
||||
fn apply_style(layout_ctx: &LayoutContext) {
|
||||
|
||||
// Right now, we only handle images.
|
||||
do self.box.node.read |node| {
|
||||
|
@ -133,8 +127,8 @@ impl StyleApplicator {
|
|||
if url.is_some() {
|
||||
// FIXME: Some sort of BASE HREF support!
|
||||
// FIXME: Parse URLs!
|
||||
let new_url = make_url(option::unwrap(url), Some(copy *self.doc_url));
|
||||
self.box.data.background_image = Some(ImageHolder(new_url, self.image_cache_task, self.reflow))
|
||||
let new_url = make_url(option::unwrap(url), Some(copy layout_ctx.doc_url));
|
||||
self.box.data.background_image = Some(ImageHolder(new_url, layout_ctx.image_cache, self.reflow))
|
||||
};
|
||||
}
|
||||
_ => { /* Ignore. */ }
|
||||
|
|
|
@ -10,6 +10,7 @@ use dom::base::{LayoutData};
|
|||
use util::color::{Color, rgb};
|
||||
use util::color::css_colors::{white, black};
|
||||
use dom::base::NodeTree;
|
||||
use layout::context::LayoutContext;
|
||||
|
||||
type SpecifiedStyle = {mut background_color : CSSValue<CSSBackgroundColor>,
|
||||
mut display_type : CSSValue<CSSDisplay>,
|
||||
|
@ -114,7 +115,7 @@ impl Node : StylePriv {
|
|||
trait StyleMethods {
|
||||
fn initialize_style_for_subtree() -> ~[@LayoutData];
|
||||
fn style() -> SpecifiedStyle;
|
||||
fn recompute_style_for_subtree(styles : ARC<Stylesheet>);
|
||||
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>);
|
||||
}
|
||||
|
||||
impl Node : StyleMethods {
|
||||
|
@ -145,31 +146,20 @@ impl Node : StyleMethods {
|
|||
#[doc="
|
||||
Performs CSS selector matching on a subtree.
|
||||
|
||||
This is, importantly, the function that updates the layout data for the node (the reader-
|
||||
auxiliary box in the RCU model) with the computed style.
|
||||
"]
|
||||
fn recompute_style_for_subtree(styles : ARC<Stylesheet>) {
|
||||
listen(|ack_chan| {
|
||||
let mut i = 0u;
|
||||
This is, importantly, the function that updates the layout data for the node (the reader-
|
||||
auxiliary box in the RCU model) with the computed style.
|
||||
"]
|
||||
fn recompute_style_for_subtree(ctx: &LayoutContext, styles : ARC<Stylesheet>) {
|
||||
let mut i = 0u;
|
||||
|
||||
// Compute the styles of each of our children in parallel
|
||||
for NodeTree.each_child(self) |kid| {
|
||||
i = i + 1u;
|
||||
let new_styles = clone(&styles);
|
||||
|
||||
// Compute the styles of each of our children in parallel
|
||||
for NodeTree.each_child(self) |kid| {
|
||||
i = i + 1u;
|
||||
let new_styles = clone(&styles);
|
||||
|
||||
task::spawn(|| {
|
||||
kid.recompute_style_for_subtree(new_styles);
|
||||
ack_chan.send(());
|
||||
})
|
||||
}
|
||||
kid.recompute_style_for_subtree(ctx, new_styles);
|
||||
}
|
||||
|
||||
self.match_css_style(*get(&styles));
|
||||
|
||||
// Make sure we have finished updating the tree before returning
|
||||
while i > 0 {
|
||||
ack_chan.recv();
|
||||
i = i - 1u;
|
||||
}
|
||||
})
|
||||
self.match_css_style(*get(&styles));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,14 @@ use gfx::render_task::{draw_solid_color, draw_image, draw_glyphs};
|
|||
use gfx::geometry::*;
|
||||
use geom::rect::Rect;
|
||||
use image::base::Image;
|
||||
use render_task::RenderContext;
|
||||
|
||||
use std::arc::{ARC, clone};
|
||||
use dvec::DVec;
|
||||
use text::glyph::Glyph;
|
||||
|
||||
struct DisplayItem {
|
||||
draw: ~fn((&DisplayItem), (&DrawTarget)),
|
||||
draw: ~fn((&DisplayItem), (&RenderContext)),
|
||||
bounds : Rect<au>, // TODO: whose coordinate system should this use?
|
||||
data : DisplayItemData
|
||||
}
|
||||
|
@ -30,21 +31,21 @@ struct GlyphRun {
|
|||
glyphs: ~[Glyph]
|
||||
}
|
||||
|
||||
fn draw_SolidColor(self: &DisplayItem, ctx: &DrawTarget) {
|
||||
fn draw_SolidColor(self: &DisplayItem, ctx: &RenderContext) {
|
||||
match self.data {
|
||||
SolidColorData(r,g,b) => draw_solid_color(ctx, &self.bounds, r, g, b),
|
||||
_ => fail
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_Glyphs(self: &DisplayItem, ctx: &DrawTarget) {
|
||||
fn draw_Glyphs(self: &DisplayItem, ctx: &RenderContext) {
|
||||
match self.data {
|
||||
GlyphData(run) => draw_glyphs(ctx, self.bounds, &run),
|
||||
_ => fail
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_Image(self: &DisplayItem, ctx: &DrawTarget) {
|
||||
fn draw_Image(self: &DisplayItem, ctx: &RenderContext) {
|
||||
match self.data {
|
||||
ImageData(img) => draw_image(ctx, self.bounds, img),
|
||||
_ => fail
|
||||
|
@ -81,11 +82,11 @@ fn Image(bounds: Rect<au>, image: ARC<~image::base::Image>) -> DisplayItem {
|
|||
type DisplayList = DVec<~DisplayItem>;
|
||||
|
||||
trait DisplayListMethods {
|
||||
fn draw(ctx: &DrawTarget);
|
||||
fn draw(ctx: &RenderContext);
|
||||
}
|
||||
|
||||
impl DisplayList : DisplayListMethods {
|
||||
fn draw(ctx: &DrawTarget) {
|
||||
fn draw(ctx: &RenderContext) {
|
||||
for self.each |item| {
|
||||
#debug["drawing %?", item];
|
||||
item.draw(item, ctx);
|
||||
|
|
|
@ -19,6 +19,7 @@ use std::arc::ARC;
|
|||
use azure::cairo::{cairo_font_face_t, cairo_scaled_font_t};
|
||||
use std::cell::Cell;
|
||||
use compositor::Compositor;
|
||||
use servo_text::font_cache::FontCache;
|
||||
|
||||
use pipes::{Port, Chan};
|
||||
|
||||
|
@ -29,6 +30,11 @@ pub enum Msg {
|
|||
ExitMsg(pipes::Chan<()>)
|
||||
}
|
||||
|
||||
struct RenderContext {
|
||||
canvas: &DrawTarget,
|
||||
font_cache: @FontCache,
|
||||
}
|
||||
|
||||
type RenderTask = comm::Chan<Msg>;
|
||||
|
||||
fn RenderTask<C: Compositor Send>(+compositor: C) -> RenderTask {
|
||||
|
@ -37,6 +43,8 @@ fn RenderTask<C: Compositor Send>(+compositor: C) -> RenderTask {
|
|||
let mut draw_target_ch = draw_target_ch;
|
||||
let mut draw_target_po = draw_target_po;
|
||||
|
||||
let font_cache = FontCache();
|
||||
|
||||
debug!("renderer: beginning rendering loop");
|
||||
|
||||
compositor.begin_drawing(draw_target_ch);
|
||||
|
@ -56,8 +64,13 @@ fn RenderTask<C: Compositor Send>(+compositor: C) -> RenderTask {
|
|||
let draw_target_ch = option::unwrap(draw_target_ch);
|
||||
|
||||
do draw_target.with_ref |draw_target| {
|
||||
clear(draw_target);
|
||||
display_list.draw(draw_target)
|
||||
let ctx = RenderContext {
|
||||
canvas: draw_target,
|
||||
font_cache: font_cache
|
||||
};
|
||||
|
||||
clear(&ctx);
|
||||
display_list.draw(&ctx)
|
||||
}
|
||||
|
||||
#debug("renderer: returning surface");
|
||||
|
@ -94,37 +107,37 @@ impl Rect<au> : ToAzureRect {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn draw_solid_color(draw_target: &DrawTarget, bounds: &Rect<au>, r: u8, g: u8, b: u8) {
|
||||
pub fn draw_solid_color(ctx: &RenderContext, bounds: &Rect<au>, r: u8, g: u8, b: u8) {
|
||||
let color = Color(r.to_float() as AzFloat,
|
||||
g.to_float() as AzFloat,
|
||||
b.to_float() as AzFloat,
|
||||
1f as AzFloat);
|
||||
|
||||
draw_target.fill_rect(bounds.to_azure_rect(), ColorPattern(color));
|
||||
ctx.canvas.fill_rect(bounds.to_azure_rect(), ColorPattern(color));
|
||||
}
|
||||
|
||||
pub fn draw_image(draw_target: &DrawTarget, bounds: Rect<au>, image: ARC<~Image>) {
|
||||
pub fn draw_image(ctx: &RenderContext, bounds: Rect<au>, image: ARC<~Image>) {
|
||||
let image = std::arc::get(&image);
|
||||
let size = Size2D(image.width as i32, image.height as i32);
|
||||
let stride = image.width * 4;
|
||||
|
||||
let azure_surface = draw_target.create_source_surface_from_data(image.data, size, stride as i32,
|
||||
let azure_surface = ctx.canvas.create_source_surface_from_data(image.data, size, stride as i32,
|
||||
B8G8R8A8);
|
||||
let source_rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat),
|
||||
Size2D(image.width as AzFloat, image.height as AzFloat));
|
||||
let dest_rect = bounds.to_azure_rect();
|
||||
let draw_surface_options = DrawSurfaceOptions(Linear, true);
|
||||
let draw_options = DrawOptions(1.0f as AzFloat, 0);
|
||||
draw_target.draw_surface(azure_surface, dest_rect, source_rect, draw_surface_options,
|
||||
ctx.canvas.draw_surface(azure_surface, dest_rect, source_rect, draw_surface_options,
|
||||
draw_options);
|
||||
}
|
||||
|
||||
pub fn draw_glyphs(draw_target: &DrawTarget, bounds: Rect<au>, text_run: &GlyphRun) {
|
||||
pub fn draw_glyphs(ctx: &RenderContext, bounds: Rect<au>, text_run: &GlyphRun) {
|
||||
use ptr::{addr_of, null};
|
||||
use vec::raw::to_ptr;
|
||||
use libc::types::common::c99::{uint16_t, uint32_t};
|
||||
use geom::point::Point2D;
|
||||
use text::font_library::FontLibrary;
|
||||
use text::font_cache::FontCache;
|
||||
use text::font::Font;
|
||||
use azure::{AzNativeFont, AzFloat, AZ_NATIVE_FONT_CAIRO_FONT_FACE};
|
||||
use azure::bindgen::{AzCreateScaledFontWithCairo,
|
||||
|
@ -133,10 +146,10 @@ pub fn draw_glyphs(draw_target: &DrawTarget, bounds: Rect<au>, text_run: &GlyphR
|
|||
AzReleaseColorPattern};
|
||||
use azure::cairo::bindgen::cairo_scaled_font_destroy;
|
||||
|
||||
let draw_target = draw_target.azure_draw_target;
|
||||
let draw_target = ctx.canvas.azure_draw_target;
|
||||
|
||||
// FIXME: The font library should not be created here
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
|
||||
let nfont: AzNativeFont = {
|
||||
|
@ -182,7 +195,8 @@ pub fn draw_glyphs(draw_target: &DrawTarget, bounds: Rect<au>, text_run: &GlyphR
|
|||
mNumGlyphs: azglyphs.len() as uint32_t
|
||||
}};
|
||||
|
||||
AzDrawTargetFillGlyphs(draw_target, azfont, addr_of(glyphbuf),
|
||||
// TODO: this call needs to move into azure_hl.rs
|
||||
AzDrawTargetFillGlyphs(ctx.canvas.azure_draw_target, azfont, addr_of(glyphbuf),
|
||||
pattern, addr_of(options), null());
|
||||
|
||||
AzReleaseColorPattern(pattern);
|
||||
|
@ -249,8 +263,8 @@ fn get_cairo_font(font: &Font) -> *cairo_scaled_font_t {
|
|||
return cfont;
|
||||
}
|
||||
|
||||
fn clear(draw_target: &DrawTarget) {
|
||||
fn clear(ctx: &RenderContext) {
|
||||
let pattern = ColorPattern(Color(1f as AzFloat, 1f as AzFloat, 1f as AzFloat, 1f as AzFloat));
|
||||
let rect = Rect(Point2D(0 as AzFloat, 0 as AzFloat), Size2D(800 as AzFloat, 600 as AzFloat));
|
||||
draw_target.fill_rect(rect, pattern);
|
||||
ctx.canvas.fill_rect(rect, pattern);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use geom::size::Size2D;
|
|||
use gfx::geometry::au;
|
||||
use image::{Image, ImageHolder};
|
||||
use layout::block::BlockFlowData;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::debug::DebugMethods;
|
||||
use layout::inline::InlineFlowData;
|
||||
use layout::root::RootFlowData;
|
||||
|
@ -85,29 +86,29 @@ impl @FlowContext : cmp::Eq {
|
|||
}
|
||||
|
||||
impl @FlowContext {
|
||||
fn bubble_widths() {
|
||||
fn bubble_widths(ctx: &LayoutContext) {
|
||||
match self.kind {
|
||||
BlockFlow(*) => self.bubble_widths_block(),
|
||||
InlineFlow(*) => self.bubble_widths_inline(),
|
||||
RootFlow(*) => self.bubble_widths_root(),
|
||||
BlockFlow(*) => self.bubble_widths_block(ctx),
|
||||
InlineFlow(*) => self.bubble_widths_inline(ctx),
|
||||
RootFlow(*) => self.bubble_widths_root(ctx),
|
||||
_ => fail fmt!("Tried to bubble_widths of flow: %?", self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
fn assign_widths() {
|
||||
fn assign_widths(ctx: &LayoutContext) {
|
||||
match self.kind {
|
||||
BlockFlow(*) => self.assign_widths_block(),
|
||||
InlineFlow(*) => self.assign_widths_inline(),
|
||||
RootFlow(*) => self.assign_widths_root(),
|
||||
BlockFlow(*) => self.assign_widths_block(ctx),
|
||||
InlineFlow(*) => self.assign_widths_inline(ctx),
|
||||
RootFlow(*) => self.assign_widths_root(ctx),
|
||||
_ => fail fmt!("Tried to assign_widths of flow: %?", self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
fn assign_height() {
|
||||
fn assign_height(ctx: &LayoutContext) {
|
||||
match self.kind {
|
||||
BlockFlow(*) => self.assign_height_block(),
|
||||
InlineFlow(*) => self.assign_height_inline(),
|
||||
RootFlow(*) => self.assign_height_root(),
|
||||
BlockFlow(*) => self.assign_height_block(ctx),
|
||||
InlineFlow(*) => self.assign_height_inline(ctx),
|
||||
RootFlow(*) => self.assign_height_root(ctx),
|
||||
_ => fail fmt!("Tried to assign_height of flow: %?", self.kind)
|
||||
}
|
||||
}
|
||||
|
@ -224,9 +225,7 @@ impl @Box {
|
|||
// how to compute its own min and pref widths, and should
|
||||
// probably cache them.
|
||||
TextBox(d) => d.runs.foldl(au(0), |sum, run| {
|
||||
let ret = au::max(sum, run.min_break_width());
|
||||
debug!("text min width: %?px", au::to_px(ret));
|
||||
ret
|
||||
au::max(sum, run.min_break_width())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -248,9 +247,7 @@ impl @Box {
|
|||
// how to compute its own min and pref widths, and should
|
||||
// probably cache them.
|
||||
TextBox(d) => d.runs.foldl(au(0), |sum, run| {
|
||||
let ret = au::max(sum, run.size().width);
|
||||
debug!("text pref width: %?px", au::to_px(ret));
|
||||
ret
|
||||
au::max(sum, run.size().width)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use geom::point::Point2D;
|
|||
use geom::size::Size2D;
|
||||
use gfx::geometry::au;
|
||||
use layout::base::{Box, FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
||||
use layout::context::LayoutContext;
|
||||
use util::tree;
|
||||
|
||||
struct BlockFlowData {
|
||||
|
@ -21,9 +22,9 @@ trait BlockLayout {
|
|||
pure fn access_block<T>(fn(&&BlockFlowData) -> T) -> T;
|
||||
pure fn with_block_box(fn(&&@Box) -> ()) -> ();
|
||||
|
||||
fn bubble_widths_block();
|
||||
fn assign_widths_block();
|
||||
fn assign_height_block();
|
||||
fn bubble_widths_block(ctx: &LayoutContext);
|
||||
fn assign_widths_block(ctx: &LayoutContext);
|
||||
fn assign_height_block(ctx: &LayoutContext);
|
||||
}
|
||||
|
||||
impl @FlowContext : BlockLayout {
|
||||
|
@ -71,7 +72,7 @@ impl @FlowContext : BlockLayout {
|
|||
/* TODO: floats */
|
||||
/* TODO: absolute contexts */
|
||||
/* TODO: inline-blocks */
|
||||
fn bubble_widths_block() {
|
||||
fn bubble_widths_block(ctx: &LayoutContext) {
|
||||
assert self.starts_block_flow();
|
||||
|
||||
let mut min_width = au(0);
|
||||
|
@ -103,7 +104,7 @@ impl @FlowContext : BlockLayout {
|
|||
Dual boxes consume some width first, and the remainder is assigned to
|
||||
all child (block) contexts. */
|
||||
|
||||
fn assign_widths_block() {
|
||||
fn assign_widths_block(ctx: &LayoutContext) {
|
||||
assert self.starts_block_flow();
|
||||
|
||||
let mut remaining_width = self.data.position.size.width;
|
||||
|
@ -125,7 +126,7 @@ impl @FlowContext : BlockLayout {
|
|||
}
|
||||
}
|
||||
|
||||
fn assign_height_block() {
|
||||
fn assign_height_block(ctx: &LayoutContext) {
|
||||
assert self.starts_block_flow();
|
||||
|
||||
let mut cur_y = au(0);
|
||||
|
|
|
@ -8,13 +8,14 @@ use dom::base::{Element, Text, Node, Doctype, Comment, NodeTree};
|
|||
use layout::base::{Box, BoxData, GenericBox, ImageBox, TextBox, BoxTree};
|
||||
use layout::base::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree};
|
||||
use layout::block::BlockFlowData;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::inline::InlineFlowData;
|
||||
use layout::root::RootFlowData;
|
||||
use layout::text::TextBoxData;
|
||||
use option::is_none;
|
||||
use util::tree;
|
||||
use servo_text::text_run::TextRun;
|
||||
use servo_text::font_library::FontLibrary;
|
||||
use servo_text::font_cache::FontCache;
|
||||
|
||||
export LayoutTreeBuilder;
|
||||
|
||||
|
@ -41,7 +42,7 @@ impl LayoutTreeBuilder {
|
|||
|
||||
/** Creates necessary box(es) and flow context(s) for the current DOM node,
|
||||
and recurses on its children. */
|
||||
fn construct_recursively(cur_node: Node, parent_ctx: @FlowContext, parent_box: @Box) {
|
||||
fn construct_recursively(layout_ctx: &LayoutContext, cur_node: Node, parent_ctx: @FlowContext, parent_box: @Box) {
|
||||
let style = cur_node.style();
|
||||
|
||||
// DEBUG
|
||||
|
@ -60,7 +61,7 @@ impl LayoutTreeBuilder {
|
|||
};
|
||||
|
||||
// first, create the proper box kind, based on node characteristics
|
||||
let box_data = match cur_node.create_box_data(display) {
|
||||
let box_data = match cur_node.create_box_data(layout_ctx, display) {
|
||||
None => return,
|
||||
Some(data) => data
|
||||
};
|
||||
|
@ -116,7 +117,7 @@ impl LayoutTreeBuilder {
|
|||
}
|
||||
// recurse
|
||||
do NodeTree.each_child(cur_node) |child_node| {
|
||||
self.construct_recursively(child_node, next_ctx, new_box); true
|
||||
self.construct_recursively(layout_ctx, child_node, next_ctx, new_box); true
|
||||
}
|
||||
|
||||
// Fixup any irregularities, such as split inlines (CSS 2.1 Section 9.2.1.1)
|
||||
|
@ -145,11 +146,11 @@ impl LayoutTreeBuilder {
|
|||
|
||||
/** entry point for box creation. Should only be
|
||||
called on root DOM element. */
|
||||
fn construct_trees(root: Node) -> Result<@Box, ()> {
|
||||
fn construct_trees(layout_ctx: &LayoutContext, root: Node) -> Result<@Box, ()> {
|
||||
self.root_ctx = Some(self.make_ctx(RootFlow(RootFlowData()), tree::empty()));
|
||||
self.root_box = Some(self.make_box(root, self.root_ctx.get(), GenericBox));
|
||||
|
||||
self.construct_recursively(root, self.root_ctx.get(), self.root_box.get());
|
||||
self.construct_recursively(layout_ctx, root, self.root_ctx.get(), self.root_box.get());
|
||||
return Ok(self.root_box.get())
|
||||
}
|
||||
|
||||
|
@ -167,18 +168,17 @@ impl LayoutTreeBuilder {
|
|||
}
|
||||
|
||||
trait PrivateBuilderMethods {
|
||||
fn create_box_data(display: CSSDisplay) -> Option<BoxData>;
|
||||
fn create_box_data(layout_ctx: &LayoutContext, display: CSSDisplay) -> Option<BoxData>;
|
||||
}
|
||||
|
||||
impl Node : PrivateBuilderMethods {
|
||||
fn create_box_data(display: CSSDisplay) -> Option<BoxData> {
|
||||
fn create_box_data(layout_ctx: &LayoutContext, display: CSSDisplay) -> Option<BoxData> {
|
||||
do self.read |node| {
|
||||
match node.kind {
|
||||
~Doctype(*) | ~Comment(*) => None,
|
||||
~Text(string) => {
|
||||
// TODO: clean this up. Fonts should not be created here.
|
||||
let flib = FontLibrary();
|
||||
let font = flib.get_test_font();
|
||||
let font = layout_ctx.font_cache.get_test_font();
|
||||
let run = TextRun(font, string);
|
||||
Some(TextBox(TextBoxData(copy string, ~[move run])))
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use dom::rcu;
|
|||
use geom::point::Point2D;
|
||||
use geom::size::Size2D;
|
||||
use gfx::geometry::au;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::base::{FlowContext, InlineFlow, BoxTree, ImageBox, TextBox, GenericBox};
|
||||
use num::Num;
|
||||
use util::tree;
|
||||
|
@ -24,9 +25,9 @@ trait InlineLayout {
|
|||
pure fn starts_inline_flow() -> bool;
|
||||
|
||||
pure fn access_inline<T>(fn(&&InlineFlowData) -> T) -> T;
|
||||
fn bubble_widths_inline();
|
||||
fn assign_widths_inline();
|
||||
fn assign_height_inline();
|
||||
fn bubble_widths_inline(ctx: &LayoutContext);
|
||||
fn assign_widths_inline(ctx: &LayoutContext);
|
||||
fn assign_height_inline(ctx: &LayoutContext);
|
||||
}
|
||||
|
||||
impl @FlowContext : InlineLayout {
|
||||
|
@ -39,7 +40,7 @@ impl @FlowContext : InlineLayout {
|
|||
}
|
||||
}
|
||||
|
||||
fn bubble_widths_inline() {
|
||||
fn bubble_widths_inline(ctx: &LayoutContext) {
|
||||
assert self.starts_inline_flow();
|
||||
|
||||
let mut min_width = au(0);
|
||||
|
@ -66,7 +67,7 @@ impl @FlowContext : InlineLayout {
|
|||
/* Recursively (top-down) determines the actual width of child
|
||||
contexts and boxes. When called on this context, the context has
|
||||
had its width set by the parent context. */
|
||||
fn assign_widths_inline() {
|
||||
fn assign_widths_inline(ctx: &LayoutContext) {
|
||||
assert self.starts_inline_flow();
|
||||
|
||||
/* Perform inline flow with the available width. */
|
||||
|
@ -117,7 +118,7 @@ impl @FlowContext : InlineLayout {
|
|||
|
||||
} // fn assign_widths_inline
|
||||
|
||||
fn assign_height_inline() {
|
||||
fn assign_height_inline(ctx: &LayoutContext) {
|
||||
// Don't need to set box or ctx heights, since that is done
|
||||
// during inline flowing.
|
||||
}
|
||||
|
|
|
@ -13,10 +13,12 @@ use dom::event::{Event, ReflowEvent};
|
|||
use gfx::render_task;
|
||||
use layout::base::Box;
|
||||
use layout::box_builder::LayoutTreeBuilder;
|
||||
use layout::context::LayoutContext;
|
||||
use render_task::RenderTask;
|
||||
use resource::image_cache_task::ImageCacheTask;
|
||||
use std::arc::ARC;
|
||||
use std::net::url::Url;
|
||||
use servo_text::font_cache::FontCache;
|
||||
|
||||
use layout::traverse::*;
|
||||
use comm::*;
|
||||
|
@ -35,52 +37,61 @@ fn LayoutTask(render_task: RenderTask, image_cache_task: ImageCacheTask) -> Layo
|
|||
|
||||
// This just keeps our dom aux objects alive
|
||||
let mut layout_data_refs = ~[];
|
||||
let font_cache = FontCache();
|
||||
|
||||
loop {
|
||||
match request.recv() {
|
||||
PingMsg(ping_channel) => ping_channel.send(content_task::PongMsg),
|
||||
ExitMsg => {
|
||||
debug!("layout: ExitMsg received");
|
||||
break;
|
||||
}
|
||||
BuildMsg(node, styles, doc_url, event_chan) => {
|
||||
debug!("layout: received layout request for: %s", doc_url.to_str());
|
||||
debug!("layout: parsed Node tree");
|
||||
node.dump();
|
||||
|
||||
do util::time::time(~"layout") {
|
||||
layout_data_refs += node.initialize_style_for_subtree();
|
||||
node.recompute_style_for_subtree(styles);
|
||||
|
||||
let root_box: @Box;
|
||||
let builder = LayoutTreeBuilder();
|
||||
match builder.construct_trees(node) {
|
||||
Ok(root) => root_box = root,
|
||||
Err(*) => fail ~"Root node should always exist"
|
||||
}
|
||||
|
||||
debug!("layout: constructed Box tree");
|
||||
root_box.dump();
|
||||
|
||||
debug!("layout: constructed Flow tree");
|
||||
root_box.ctx.dump();
|
||||
|
||||
/* resolve styles (convert relative values) down the box tree */
|
||||
let reflow_cb: fn~() = || event_chan.send(ReflowEvent);
|
||||
apply_style(root_box, &doc_url, image_cache_task, reflow_cb);
|
||||
|
||||
/* perform layout passes over the flow tree */
|
||||
let root_flow = root_box.ctx;
|
||||
do root_flow.traverse_postorder |f| { f.bubble_widths() }
|
||||
root_flow.data.position.origin = au::zero_point();
|
||||
root_flow.data.position.size.width = au::from_px(800); // TODO: window/frame size
|
||||
do root_flow.traverse_preorder |f| { f.assign_widths() }
|
||||
do root_flow.traverse_postorder |f| { f.assign_height() }
|
||||
|
||||
let dlist = build_display_list(root_box);
|
||||
render_task.send(render_task::RenderMsg(dlist));
|
||||
PingMsg(ping_channel) => ping_channel.send(content_task::PongMsg),
|
||||
ExitMsg => {
|
||||
debug!("layout: ExitMsg received");
|
||||
break;
|
||||
}
|
||||
BuildMsg(node, styles, doc_url, event_chan) => {
|
||||
debug!("layout: received layout request for: %s", doc_url.to_str());
|
||||
debug!("layout: parsed Node tree");
|
||||
node.dump();
|
||||
|
||||
let layout_ctx = LayoutContext {
|
||||
image_cache: image_cache_task,
|
||||
font_cache: font_cache,
|
||||
doc_url: doc_url,
|
||||
};
|
||||
|
||||
do util::time::time(~"layout") {
|
||||
layout_data_refs += node.initialize_style_for_subtree();
|
||||
node.recompute_style_for_subtree(&layout_ctx, styles);
|
||||
|
||||
let root_box: @Box;
|
||||
let builder = LayoutTreeBuilder();
|
||||
match builder.construct_trees(&layout_ctx, node) {
|
||||
Ok(root) => root_box = root,
|
||||
Err(*) => fail ~"Root node should always exist"
|
||||
}
|
||||
|
||||
debug!("layout: constructed Box tree");
|
||||
root_box.dump();
|
||||
|
||||
debug!("layout: constructed Flow tree");
|
||||
root_box.ctx.dump();
|
||||
|
||||
/* resolve styles (convert relative values) down the box tree */
|
||||
let reflow_cb: fn~() = || event_chan.send(ReflowEvent);
|
||||
apply_style(&layout_ctx, root_box, reflow_cb);
|
||||
|
||||
/* perform layout passes over the flow tree */
|
||||
let root_flow = root_box.ctx;
|
||||
do root_flow.traverse_postorder |f| { f.bubble_widths(&layout_ctx) }
|
||||
// TODO: window/frame size should be set inside RootBox::assign_widths
|
||||
root_flow.data.position.origin = au::zero_point();
|
||||
root_flow.data.position.size.width = au::from_px(800);
|
||||
// end TODO
|
||||
do root_flow.traverse_preorder |f| { f.assign_widths(&layout_ctx) }
|
||||
do root_flow.traverse_postorder |f| { f.assign_height(&layout_ctx) }
|
||||
|
||||
let dlist = build_display_list(root_box);
|
||||
render_task.send(render_task::RenderMsg(dlist));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use geom::point::Point2D;
|
|||
use geom::size::Size2D;
|
||||
use gfx::geometry::au;
|
||||
use layout::base::{Box, FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
||||
use layout::context::LayoutContext;
|
||||
use util::tree;
|
||||
|
||||
struct RootFlowData {
|
||||
|
@ -20,9 +21,9 @@ trait RootLayout {
|
|||
pure fn starts_root_flow() -> bool;
|
||||
pure fn access_root<T>(fn(&&RootFlowData) -> T) -> T;
|
||||
|
||||
fn bubble_widths_root();
|
||||
fn assign_widths_root();
|
||||
fn assign_height_root();
|
||||
fn bubble_widths_root(ctx: &LayoutContext);
|
||||
fn assign_widths_root(ctx: &LayoutContext);
|
||||
fn assign_height_root(ctx: &LayoutContext);
|
||||
}
|
||||
|
||||
impl @FlowContext : RootLayout {
|
||||
|
@ -42,21 +43,21 @@ impl @FlowContext : RootLayout {
|
|||
}
|
||||
|
||||
/* defer to the block algorithm */
|
||||
fn bubble_widths_root() {
|
||||
fn bubble_widths_root(ctx: &LayoutContext) {
|
||||
assert self.starts_root_flow();
|
||||
self.bubble_widths_block()
|
||||
self.bubble_widths_block(ctx)
|
||||
}
|
||||
|
||||
fn assign_widths_root() {
|
||||
fn assign_widths_root(ctx: &LayoutContext) {
|
||||
assert self.starts_root_flow();
|
||||
|
||||
/* TODO: should determine frame width here, not in
|
||||
LayoutTask. Until then, defer to block. */
|
||||
self.assign_widths_block() }
|
||||
self.assign_widths_block(ctx) }
|
||||
|
||||
fn assign_height_root() {
|
||||
fn assign_height_root(ctx: &LayoutContext) {
|
||||
assert self.starts_root_flow();
|
||||
|
||||
self.assign_height_block();
|
||||
self.assign_height_block(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@ use au = gfx::geometry;
|
|||
use geom::size::Size2D;
|
||||
use gfx::geometry::au;
|
||||
use servo_text::text_run::TextRun;
|
||||
use servo_text::font_library::FontLibrary;
|
||||
use servo_text::font_cache::FontCache;
|
||||
use layout::base::{TextBox, Box};
|
||||
use layout::context::LayoutContext;
|
||||
|
||||
struct TextBoxData {
|
||||
text: ~str,
|
||||
|
@ -20,20 +21,18 @@ fn TextBoxData(text: ~str, runs: ~[TextRun]) -> TextBoxData {
|
|||
}
|
||||
|
||||
trait TextLayout {
|
||||
fn reflow_text();
|
||||
fn reflow_text(ctx: &LayoutContext);
|
||||
}
|
||||
|
||||
#[doc="The main reflow routine for text layout."]
|
||||
impl @Box : TextLayout {
|
||||
fn reflow_text() {
|
||||
fn reflow_text(ctx: &LayoutContext) {
|
||||
let d = match self.kind {
|
||||
TextBox(d) => { d }
|
||||
_ => { fail ~"expected text box in reflow_text!" }
|
||||
};
|
||||
|
||||
// FIXME: The font library should not be initialized here
|
||||
let flib = FontLibrary();
|
||||
let font = flib.get_test_font();
|
||||
let font = ctx.font_cache.get_test_font();
|
||||
|
||||
// Do line breaking.
|
||||
let mut current = TextRun(font, d.text);
|
||||
|
|
|
@ -4,28 +4,28 @@ use layout::base::{Box, BoxTree};
|
|||
use layout::base::{FlowContext, FlowTree};
|
||||
|
||||
trait BoxTraversals {
|
||||
fn traverse_preorder(preorder_cb: ~fn(@Box));
|
||||
fn traverse_preorder(preorder_cb: &fn(@Box));
|
||||
}
|
||||
|
||||
impl @Box : BoxTraversals {
|
||||
fn traverse_preorder(preorder_cb: ~fn(@Box)) {
|
||||
fn traverse_preorder(preorder_cb: &fn(@Box)) {
|
||||
preorder_cb(self);
|
||||
do BoxTree.each_child(self) |child| { child.traverse_preorder(preorder_cb); true }
|
||||
}
|
||||
}
|
||||
|
||||
trait FlowContextTraversals {
|
||||
fn traverse_preorder(preorder_cb: ~fn(@FlowContext));
|
||||
fn traverse_postorder(postorder_cb: ~fn(@FlowContext));
|
||||
fn traverse_preorder(preorder_cb: &fn(@FlowContext));
|
||||
fn traverse_postorder(postorder_cb: &fn(@FlowContext));
|
||||
}
|
||||
|
||||
impl @FlowContext : FlowContextTraversals {
|
||||
fn traverse_preorder(preorder_cb: ~fn(@FlowContext)) {
|
||||
fn traverse_preorder(preorder_cb: &fn(@FlowContext)) {
|
||||
preorder_cb(self);
|
||||
do FlowTree.each_child(self) |child| { child.traverse_preorder(preorder_cb); true }
|
||||
}
|
||||
|
||||
fn traverse_postorder(postorder_cb: ~fn(@FlowContext)) {
|
||||
fn traverse_postorder(postorder_cb: &fn(@FlowContext)) {
|
||||
do FlowTree.each_child(self) |child| { child.traverse_postorder(postorder_cb); true }
|
||||
postorder_cb(self);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ mod layout {
|
|||
mod base;
|
||||
mod block;
|
||||
mod box_builder;
|
||||
mod context;
|
||||
mod debug;
|
||||
mod display_list_builder;
|
||||
mod inline;
|
||||
|
@ -97,12 +98,12 @@ mod platform {
|
|||
mod text {
|
||||
export glyph;
|
||||
export text_run;
|
||||
export font_library;
|
||||
export font;
|
||||
export font_cache;
|
||||
export shaper;
|
||||
|
||||
mod font;
|
||||
mod font_library;
|
||||
mod font_cache;
|
||||
mod glyph;
|
||||
mod native_font {
|
||||
#[cfg(target_os = "macos")]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub use font_cache::FontCache;
|
||||
export Font, FontMetrics, test_font_bin, create_test_font;
|
||||
|
||||
use glyph::GlyphIndex;
|
||||
|
@ -5,7 +6,6 @@ use vec_to_ptr = vec::raw::to_ptr;
|
|||
use libc::{ c_int, c_double, c_ulong };
|
||||
use ptr::{ null, addr_of };
|
||||
use native_font::NativeFont;
|
||||
use font_library::FontLibrary;
|
||||
|
||||
#[doc = "
|
||||
A font handle. Layout can use this to calculate glyph metrics
|
||||
|
@ -13,7 +13,7 @@ and the renderer can use it to render text.
|
|||
"]
|
||||
struct Font {
|
||||
// A back reference to keep the library alive
|
||||
lib: @FontLibrary,
|
||||
lib: @FontCache,
|
||||
fontbuf: @~[u8],
|
||||
native_font: NativeFont,
|
||||
metrics: FontMetrics
|
||||
|
@ -36,7 +36,7 @@ impl Font {
|
|||
}
|
||||
}
|
||||
|
||||
fn Font(lib: @FontLibrary, fontbuf: @~[u8], +native_font: NativeFont, +metrics: FontMetrics) -> Font {
|
||||
fn Font(lib: @FontCache, fontbuf: @~[u8], +native_font: NativeFont, +metrics: FontMetrics) -> Font {
|
||||
Font {
|
||||
lib: lib,
|
||||
fontbuf : fontbuf,
|
||||
|
@ -67,7 +67,7 @@ fn should_destruct_on_fail_without_leaking() {
|
|||
#[test];
|
||||
#[should_fail];
|
||||
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let _font = lib.get_test_font();
|
||||
fail;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ fn should_destruct_on_fail_without_leaking() {
|
|||
fn should_get_glyph_indexes() {
|
||||
#[test];
|
||||
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let font = lib.get_test_font();
|
||||
let glyph_idx = font.glyph_index('w');
|
||||
assert glyph_idx == Some(40u);
|
||||
|
@ -84,7 +84,7 @@ fn should_get_glyph_indexes() {
|
|||
fn should_get_glyph_advance() {
|
||||
#[test];
|
||||
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let font = lib.get_test_font();
|
||||
let x = font.glyph_h_advance(40u);
|
||||
assert x == 15;
|
||||
|
@ -100,7 +100,7 @@ fn should_get_glyph_advance_stress() {
|
|||
let (chan, port) = pipes::stream();
|
||||
ports += [@move port];
|
||||
do task::spawn {
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let font = lib.get_test_font();
|
||||
let x = font.glyph_h_advance(40u);
|
||||
assert x == 15;
|
||||
|
@ -118,7 +118,7 @@ fn should_be_able_to_create_instances_in_multiple_threads() {
|
|||
|
||||
for iter::repeat(10u) {
|
||||
do task::spawn {
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let _font = lib.get_test_font();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
export FontLibrary, native;
|
||||
|
||||
export FontCache, native;
|
||||
use font::{Font, test_font_bin};
|
||||
|
||||
struct FontLibrary {
|
||||
struct FontCache {
|
||||
// FIXME: This is a hack to hold onto a boxed reference to
|
||||
// the self pointer until explicit self types work on methods.
|
||||
// This is a huge space leak.
|
||||
mut at_self: Option<@FontLibrary>,
|
||||
native_lib: native::NativeFontLibrary,
|
||||
mut at_self: Option<@FontCache>,
|
||||
native_lib: native::NativeFontCache,
|
||||
|
||||
drop {
|
||||
native::destroy_native_lib(&self.native_lib);
|
||||
}
|
||||
}
|
||||
|
||||
impl FontLibrary {
|
||||
impl FontCache {
|
||||
fn get_font() -> @Font {
|
||||
assert self.at_self.is_some();
|
||||
match create_font(self.at_self.get(), &self.native_lib) {
|
||||
|
@ -28,8 +27,8 @@ impl FontLibrary {
|
|||
}
|
||||
}
|
||||
|
||||
fn FontLibrary() -> @FontLibrary {
|
||||
let lib = @FontLibrary {
|
||||
fn FontCache() -> @FontCache {
|
||||
let lib = @FontCache {
|
||||
mut at_self: None,
|
||||
native_lib: native::create_native_lib()
|
||||
};
|
||||
|
@ -38,7 +37,7 @@ fn FontLibrary() -> @FontLibrary {
|
|||
return lib;
|
||||
}
|
||||
|
||||
fn create_font(lib: @FontLibrary, native_lib: &native::NativeFontLibrary) -> Result<@Font, ()> {
|
||||
fn create_font(lib: @FontCache, native_lib: &native::NativeFontCache) -> Result<@Font, ()> {
|
||||
let font_bin = @test_font_bin();
|
||||
let native_font = native_font::create(native_lib, font_bin);
|
||||
let native_font = if native_font.is_ok() {
|
||||
|
@ -57,9 +56,9 @@ mod native {
|
|||
use freetype::{FT_Library, FT_Error};
|
||||
use freetype::bindgen::{FT_Init_FreeType, FT_Done_FreeType};
|
||||
|
||||
type NativeFontLibrary = FT_Library;
|
||||
type NativeFontCache = FT_Library;
|
||||
|
||||
fn create_native_lib() -> NativeFontLibrary {
|
||||
fn create_native_lib() -> NativeFontCache {
|
||||
let lib: FT_Library = null();
|
||||
let res = FT_Init_FreeType(addr_of(lib));
|
||||
// FIXME: error handling
|
||||
|
@ -67,7 +66,7 @@ mod native {
|
|||
return lib;
|
||||
}
|
||||
|
||||
fn destroy_native_lib(native_lib: &NativeFontLibrary) {
|
||||
fn destroy_native_lib(native_lib: &NativeFontCache) {
|
||||
assert native_lib.is_not_null();
|
||||
FT_Done_FreeType(*native_lib);
|
||||
}
|
||||
|
@ -75,14 +74,14 @@ mod native {
|
|||
|
||||
#[cfg(target_os = "macos")]
|
||||
mod native {
|
||||
type NativeFontLibrary = ();
|
||||
type NativeFontCache = ();
|
||||
|
||||
fn create_native_lib() -> NativeFontLibrary { () }
|
||||
fn destroy_native_lib(_native_lib: &NativeFontLibrary) { }
|
||||
fn create_native_lib() -> NativeFontCache { () }
|
||||
fn destroy_native_lib(_native_lib: &NativeFontCache) { }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_get_fonts() {
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
lib.get_font();
|
||||
}
|
|
@ -9,7 +9,7 @@ font resources needed by the graphics layer to draw glyphs.
|
|||
|
||||
export NativeFont, create;
|
||||
|
||||
use font_library::native::NativeFontLibrary;
|
||||
use font_cache::native::NativeFontCache;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
type NativeFont/& = quartz_native_font::QuartzNativeFont;
|
||||
|
@ -18,12 +18,12 @@ type NativeFont/& = quartz_native_font::QuartzNativeFont;
|
|||
type NativeFont/& = ft_native_font::FreeTypeNativeFont;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn create(_native_lib: &NativeFontLibrary, buf: @~[u8]) -> Result<NativeFont, ()> {
|
||||
fn create(_native_lib: &NativeFontCache, buf: @~[u8]) -> Result<NativeFont, ()> {
|
||||
quartz_native_font::create(buf)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn create(native_lib: &NativeFontLibrary, buf: @~[u8]) -> Result<NativeFont, ()> {
|
||||
fn create(native_lib: &NativeFontCache, buf: @~[u8]) -> Result<NativeFont, ()> {
|
||||
ft_native_font::create(native_lib, buf)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use glyph::{Glyph, GlyphPos};
|
|||
use ptr::{null, addr_of, offset};
|
||||
use gfx::geometry::au;
|
||||
use geom::point::Point2D;
|
||||
use font_library::FontLibrary;
|
||||
use font_cache::FontCache;
|
||||
|
||||
use unsafe::reinterpret_cast;
|
||||
use harfbuzz::{HB_MEMORY_MODE_READONLY,
|
||||
|
@ -148,7 +148,7 @@ fn should_get_glyph_indexes() {
|
|||
#[test];
|
||||
#[ignore(cfg(target_os = "macos"), reason = "bad metrics")];
|
||||
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let font = lib.get_test_font();
|
||||
let glyphs = shape_text(font, ~"firecracker");
|
||||
let idxs = glyphs.map(|glyph| glyph.index);
|
||||
|
@ -159,7 +159,7 @@ fn should_get_glyph_h_advance() {
|
|||
#[test];
|
||||
#[ignore(cfg(target_os = "macos"), reason = "bad metrics")];
|
||||
|
||||
let lib = FontLibrary();
|
||||
let lib = FontCache();
|
||||
let font = lib.get_test_font();
|
||||
let glyphs = shape_text(font, ~"firecracker");
|
||||
let actual = glyphs.map(|g| g.pos.advance.x);
|
||||
|
|
|
@ -3,7 +3,7 @@ use geom::point::Point2D;
|
|||
use geom::size::Size2D;
|
||||
use gfx::geometry::au;
|
||||
use libc::{c_void};
|
||||
use font_library::FontLibrary;
|
||||
use font_cache::FontCache;
|
||||
use font::Font;
|
||||
use glyph::Glyph;
|
||||
use shaper::shape_text;
|
||||
|
@ -135,7 +135,7 @@ fn iter_indivisible_slices(font: &Font, text: &r/str,
|
|||
|
||||
#[test]
|
||||
fn test_calc_min_break_width1() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let actual = calc_min_break_width(font, ~"firecracker");
|
||||
let expected = au::from_px(84);
|
||||
|
@ -144,7 +144,7 @@ fn test_calc_min_break_width1() {
|
|||
|
||||
#[test]
|
||||
fn test_calc_min_break_width2() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let actual = calc_min_break_width(font, ~"firecracker yumyum");
|
||||
let expected = au::from_px(84);
|
||||
|
@ -153,7 +153,7 @@ fn test_calc_min_break_width2() {
|
|||
|
||||
#[test]
|
||||
fn test_calc_min_break_width3() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let actual = calc_min_break_width(font, ~"yumyum firecracker");
|
||||
let expected = au::from_px(84);
|
||||
|
@ -162,7 +162,7 @@ fn test_calc_min_break_width3() {
|
|||
|
||||
#[test]
|
||||
fn test_calc_min_break_width4() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let actual = calc_min_break_width(font, ~"yumyum firecracker yumyum");
|
||||
let expected = au::from_px(84);
|
||||
|
@ -171,7 +171,7 @@ fn test_calc_min_break_width4() {
|
|||
|
||||
#[test]
|
||||
fn test_iter_indivisible_slices() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let mut slices = ~[];
|
||||
for iter_indivisible_slices(font, "firecracker yumyum woopwoop") |slice| {
|
||||
|
@ -182,7 +182,7 @@ fn test_iter_indivisible_slices() {
|
|||
|
||||
#[test]
|
||||
fn test_iter_indivisible_slices_trailing_whitespace() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let mut slices = ~[];
|
||||
for iter_indivisible_slices(font, "firecracker ") |slice| {
|
||||
|
@ -193,7 +193,7 @@ fn test_iter_indivisible_slices_trailing_whitespace() {
|
|||
|
||||
#[test]
|
||||
fn test_iter_indivisible_slices_leading_whitespace() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let mut slices = ~[];
|
||||
for iter_indivisible_slices(font, " firecracker") |slice| {
|
||||
|
@ -204,7 +204,7 @@ fn test_iter_indivisible_slices_leading_whitespace() {
|
|||
|
||||
#[test]
|
||||
fn test_iter_indivisible_slices_empty() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let mut slices = ~[];
|
||||
for iter_indivisible_slices(font, "") |slice| {
|
||||
|
@ -215,7 +215,7 @@ fn test_iter_indivisible_slices_empty() {
|
|||
|
||||
#[test]
|
||||
fn test_split() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let run = TextRun(font, ~"firecracker yumyum");
|
||||
let break_runs = run.split(font, run.min_break_width());
|
||||
|
@ -225,7 +225,7 @@ fn test_split() {
|
|||
|
||||
#[test]
|
||||
fn test_split2() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let run = TextRun(font, ~"firecracker yum yum yum yum yum");
|
||||
let break_runs = run.split(font, run.min_break_width());
|
||||
|
@ -235,7 +235,7 @@ fn test_split2() {
|
|||
|
||||
#[test]
|
||||
fn test_split3() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let run = TextRun(font, ~"firecracker firecracker");
|
||||
let break_runs = run.split(font, run.min_break_width() + au::from_px(10));
|
||||
|
@ -247,7 +247,7 @@ fn test_split3() {
|
|||
#[test]
|
||||
#[ignore(cfg(target_os = "macos"))]
|
||||
fn should_calculate_the_total_size() {
|
||||
let flib = FontLibrary();
|
||||
let flib = FontCache();
|
||||
let font = flib.get_test_font();
|
||||
let run = TextRun(font, ~"firecracker");
|
||||
let expected = Size2D(au::from_px(84), au::from_px(20));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue