servo: Introduce text run and glyph classes

Source-Repo: https://github.com/servo/servo
Source-Revision: 0f5eb549ab5c32dc118112311618938e55629b68
This commit is contained in:
Patrick Walton 2012-05-17 17:35:50 -07:00
Родитель bc517a6d9d
Коммит 23e895c155
6 изменённых файлов: 127 добавлений и 13 удалений

Просмотреть файл

@ -8,13 +8,14 @@ import gfx::geom::{size, rect, point, au, zero_size_au};
import /*layout::*/block::block_layout_methods;
import /*layout::*/inline::inline_layout_methods;
import /*layout::*/style::style::*;
import /*layout::*/text::{text_box, text_layout_methods};
import util::tree;
enum box_kind {
bk_block,
bk_inline,
bk_intrinsic(@geom::size<au>),
bk_text(str)
bk_text(@text_box)
}
enum box = {
@ -84,7 +85,7 @@ impl layout_methods for @box {
bk_block { self.reflow_block(available_width) }
bk_inline { self.reflow_inline(available_width) }
bk_intrinsic(size) { self.reflow_intrinsic(*size) }
bk_text(s) { self.reflow_text(s) }
bk_text(subbox) { self.reflow_text(available_width, subbox) }
}
}
@ -95,14 +96,6 @@ impl layout_methods for @box {
#debug["reflow_intrinsic size=%?", self.bounds];
}
#[doc="The reflow routine for text frames."]
fn reflow_text(text: str) {
self.bounds.size = {
mut width: au(text.len() as int * 60 * 10),
mut height: au(60 * 14)
};
}
#[doc="Dumps the box tree, for debugging."]
fn dump() {
self.dump_indent(0u);

Просмотреть файл

@ -7,6 +7,7 @@ import /*layout::*/base::{bk_block, bk_inline, bk_intrinsic, bk_text, box};
import /*layout::*/base::{box_kind, btree, node_methods, ntree, rd_tree_ops};
import /*layout::*/base::wr_tree_ops;
import /*layout::*/style::style::{di_block, di_inline, style_methods};
import /*layout::*/text::text_box;
import util::tree;
export box_builder_methods;
@ -118,9 +119,9 @@ impl box_builder_priv for node {
"]
fn determine_box_kind() -> box_kind {
alt self.rd({ |n| n.kind }) {
nk_img(size) { bk_intrinsic(@size) }
nk_div { bk_block }
nk_text(s) { bk_text(s) }
nk_img(size) { bk_intrinsic(@size) }
nk_div { bk_block }
nk_text(s) { bk_text(@text_box(s)) }
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
#[doc="Text layout."]
import gfx::geom::au;
import /*layout::*/base::*; // FIXME: Can't get around import *; resolve bug.
import servo_text::text_run::text_run;
class text_box {
let text: str;
let mut run: option<text_run>;
new(text: str) {
self.text = text;
self.run = none;
}
}
#[doc="The main reflow routine for text layout."]
impl text_layout_methods for @box {
fn reflow_text(_available_width: au, subbox: @text_box) {
alt self.kind {
bk_text(*) { /* ok */ }
_ { fail "expected text box in reflow_text!" }
};
let run = text_run(subbox.text);
subbox.run = some(run);
run.shape();
self.bounds.size = {
mut width:
alt vec::last_opt(run.glyphs.get()) {
some(glyph) {
au(*glyph.pos.offset.x + *glyph.pos.advance.x)
}
none { au(0) }
},
mut height: au(60 * 14)
};
}
}

Просмотреть файл

@ -43,6 +43,7 @@ mod layout {
mod display_list;
mod inline;
mod layout;
mod text;
}
mod parser {
@ -55,6 +56,11 @@ mod platform {
mod osmain;
}
mod text {
mod glyph;
mod text_run;
}
mod util {
mod tree;
}
@ -66,3 +72,6 @@ mod content {
mod opts;
mod engine;
import servo_text = text;

Просмотреть файл

@ -0,0 +1,30 @@
import gfx::geom::{au, point, px_to_au};
#[doc="The position of a glyph on the screen."]
class glyph_pos {
let advance: point<au>;
let offset: point<au>;
new(hb_pos: harfbuzz::hb_glyph_position_t) {
self.advance = {
mut x: px_to_au(hb_pos.x_advance as int),
mut y: px_to_au(hb_pos.y_advance as int)
};
self.offset = {
mut x: px_to_au(hb_pos.x_offset as int),
mut y: px_to_au(hb_pos.y_offset as int)
};
}
}
#[doc="A single glyph."]
class glyph {
let codepoint: uint;
let pos: glyph_pos;
new(codepoint: uint, pos: glyph_pos) {
self.codepoint = codepoint;
self.pos = pos;
}
}

Просмотреть файл

@ -0,0 +1,40 @@
import libc::{c_void};
import libc::types::common::c99::int32_t;
import text::glyph::{glyph, glyph_pos};
#[doc="A single, unbroken line of text."]
class text_run {
let text: str;
let mut glyphs: option<[glyph]>;
new(text: str) {
self.text = text;
self.glyphs = none;
}
#[doc="
Shapes text. This determines the location of each glyph and determines
line break positions.
"]
fn shape() {
let mut glyphs = [];
let mut cur_x = 0u;
for self.text.each_char {
|ch|
// TODO: Use HarfBuzz!
let hb_pos = {
x_advance: 10 as int32_t,
y_advance: 0 as int32_t,
x_offset: cur_x as int32_t,
y_offset: 0 as int32_t,
var: 0
};
vec::push(glyphs, glyph(ch as uint, glyph_pos(hb_pos)));
cur_x += 10u;
};
self.glyphs = some(/* move */ glyphs);
}
}