зеркало из https://github.com/mozilla/gecko-dev.git
servo: Introduce text run and glyph classes
Source-Repo: https://github.com/servo/servo Source-Revision: 0f5eb549ab5c32dc118112311618938e55629b68
This commit is contained in:
Родитель
bc517a6d9d
Коммит
23e895c155
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче