Upgrade to latest Rust.

This commit is contained in:
Jack Moffitt 2013-12-20 22:04:46 -07:00
parent 728fb9a7de
commit a7ef1cd35e
127 changed files with 1892 additions and 2501 deletions

View file

@ -150,14 +150,14 @@ pub struct ClipDisplayItem<E> {
need_clip: bool
}
pub enum DisplayItemIterator<'self,E> {
pub enum DisplayItemIterator<'a,E> {
EmptyDisplayItemIterator,
ParentDisplayItemIterator(VecIterator<'self,DisplayItem<E>>),
ParentDisplayItemIterator(VecIterator<'a,DisplayItem<E>>),
}
impl<'self,E> Iterator<&'self DisplayItem<E>> for DisplayItemIterator<'self,E> {
impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> {
#[inline]
fn next(&mut self) -> Option<&'self DisplayItem<E>> {
fn next(&mut self) -> Option<&'a DisplayItem<E>> {
match *self {
EmptyDisplayItemIterator => None,
ParentDisplayItemIterator(ref mut subiterator) => subiterator.next(),
@ -192,12 +192,12 @@ impl<E> DisplayItem<E> {
let text_run = text.text_run.get();
let font = render_context.font_ctx.get_font_by_descriptor(&text_run.font_descriptor).unwrap();
let font_metrics = font.with_borrow( |font| {
let font_metrics = font.borrow().with(|font| {
font.metrics.clone()
});
let origin = text.base.bounds.origin;
let baseline_origin = Point2D(origin.x, origin.y + font_metrics.ascent);
font.with_mut_borrow( |font| {
font.borrow().with_mut(|font| {
font.draw_text_into_context(render_context,
text.text_run.get(),
&text.range,
@ -264,10 +264,10 @@ impl<E> DisplayItem<E> {
pub fn children<'a>(&'a self) -> DisplayItemIterator<'a,E> {
match *self {
ClipDisplayItemClass(ref clip) => ParentDisplayItemIterator(clip.child_list.iter()),
SolidColorDisplayItemClass(*) |
TextDisplayItemClass(*) |
ImageDisplayItemClass(*) |
BorderDisplayItemClass(*) => EmptyDisplayItemIterator,
SolidColorDisplayItemClass(..) |
TextDisplayItemClass(..) |
ImageDisplayItemClass(..) |
BorderDisplayItemClass(..) => EmptyDisplayItemIterator,
}
}

View file

@ -10,13 +10,11 @@ use geom::{Point2D, Rect, Size2D};
use std::cast;
use std::ptr;
use std::str;
use std::vec;
use std::rc::RcMut;
use std::rc::Rc;
use std::cell::RefCell;
use servo_util::cache::{Cache, HashCache};
use servo_util::range::Range;
use servo_util::time::ProfilerChan;
use style::computed_values::{text_decoration, font_weight, font_style};
use color::Color;
use font_context::FontContext;
use servo_util::geometry::Au;
@ -73,7 +71,7 @@ impl FontTableTagConversions for FontTableTag {
}
pub trait FontTableMethods {
fn with_buffer(&self, &fn(*u8, uint));
fn with_buffer(&self, |*u8, uint|);
}
#[deriving(Clone)]
@ -108,12 +106,6 @@ pub struct FontStyle {
pub type SpecifiedFontStyle = FontStyle;
pub type UsedFontStyle = FontStyle;
// FIXME: move me to layout
struct ResolvedFont {
group: @FontGroup,
style: SpecifiedFontStyle,
}
// FontDescriptor serializes a specific font and used font style
// options, such as point size.
@ -153,11 +145,11 @@ pub struct FontGroup {
// style of the first western font in group, which is
// used for purposes of calculating text run metrics.
style: UsedFontStyle,
fonts: ~[RcMut<Font>]
fonts: ~[Rc<RefCell<Font>>]
}
impl FontGroup {
pub fn new(families: ~[~str], style: &UsedFontStyle, fonts: ~[RcMut<Font>]) -> FontGroup {
pub fn new(families: ~[~str], style: &UsedFontStyle, fonts: ~[Rc<RefCell<Font>>]) -> FontGroup {
FontGroup {
families: families,
style: (*style).clone(),
@ -173,7 +165,7 @@ impl FontGroup {
assert!(self.fonts.len() > 0);
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
self.fonts[0].with_mut_borrow(|font| {
self.fonts[0].borrow().with_mut(|font| {
TextRun::new(font, text.clone(), decoration)
})
}
@ -218,18 +210,16 @@ pub struct Font {
style: UsedFontStyle,
metrics: FontMetrics,
backend: BackendType,
profiler_chan: ProfilerChan,
shape_cache: HashCache<~str, Arc<GlyphStore>>,
glyph_advance_cache: HashCache<u32, FractionalPixel>,
}
impl<'self> Font {
impl<'a> Font {
pub fn new_from_buffer(ctx: &FontContext,
buffer: ~[u8],
style: &SpecifiedFontStyle,
backend: BackendType,
profiler_chan: ProfilerChan)
-> Result<RcMut<Font>, ()> {
backend: BackendType)
-> Result<Rc<RefCell<Font>>, ()> {
let handle = FontHandleMethods::new_from_buffer(&ctx.handle, buffer, style);
let handle: FontHandle = if handle.is_ok() {
handle.unwrap()
@ -240,22 +230,21 @@ impl<'self> Font {
let metrics = handle.get_metrics();
// TODO(Issue #179): convert between specified and used font style here?
return Ok(RcMut::new(Font {
return Ok(Rc::from_mut(RefCell::new(Font {
handle: handle,
azure_font: None,
shaper: None,
style: (*style).clone(),
metrics: metrics,
backend: backend,
profiler_chan: profiler_chan,
shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(),
}));
})));
}
pub fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
style: &SpecifiedFontStyle, backend: BackendType,
profiler_chan: ProfilerChan) -> Font {
style: &SpecifiedFontStyle, backend: BackendType)
-> Font {
let metrics = handle.get_metrics();
Font {
@ -265,15 +254,14 @@ impl<'self> Font {
style: (*style).clone(),
metrics: metrics,
backend: backend,
profiler_chan: profiler_chan,
shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(),
}
}
pub fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
style: &SpecifiedFontStyle, backend: BackendType,
profiler_chan: ProfilerChan) -> Result<RcMut<Font>,()> {
style: &SpecifiedFontStyle, backend: BackendType)
-> Result<Rc<RefCell<Font>>,()> {
// TODO(Issue #179): convert between specified and used font style here?
let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
@ -281,15 +269,15 @@ impl<'self> Font {
Err(()) => return Err(())
};
return Ok(RcMut::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend, profiler_chan)));
return Ok(Rc::from_mut(RefCell::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend))));
}
fn make_shaper(&'self mut self) -> &'self Shaper {
fn make_shaper(&'a mut self) -> &'a Shaper {
// fast path: already created a shaper
match self.shaper {
Some(ref shaper) => {
let s: &'self Shaper = shaper;
return s;
Some(ref shaper) => {
let s: &'a Shaper = shaper;
return s;
},
None => {}
}
@ -349,7 +337,6 @@ impl<'self> Font {
impl Font {
#[fixed_stack_segment]
pub fn draw_text_into_context(&mut self,
rctx: &RenderContext,
run: &~TextRun,
@ -399,8 +386,8 @@ impl Font {
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
let glyphbuf = struct__AzGlyphBuffer {
mGlyphs: vec::raw::to_ptr(azglyphs),
mNumGlyphs: azglyph_buf_len as uint32_t
mGlyphs: azglyphs.as_ptr(),
mNumGlyphs: azglyph_buf_len as uint32_t
};
unsafe {
@ -441,11 +428,11 @@ impl Font {
//FIXME (ksh8281)
self.make_shaper();
do self.shape_cache.find_or_create(&text) |txt| {
self.shape_cache.find_or_create(&text, |txt| {
let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace);
self.shaper.get_ref().shape_text(*txt, &mut glyphs);
Arc::new(glyphs)
}
})
}
pub fn get_descriptor(&self) -> FontDescriptor {
@ -457,12 +444,12 @@ impl Font {
}
pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel {
do self.glyph_advance_cache.find_or_create(&glyph) |glyph| {
self.glyph_advance_cache.find_or_create(&glyph, |glyph| {
match self.handle.glyph_h_advance(*glyph) {
Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel
}
}
})
}
}

View file

@ -15,7 +15,8 @@ use platform::font_context::FontContextHandle;
use azure::azure_hl::BackendType;
use std::hashmap::HashMap;
use std::rc::RcMut;
use std::rc::Rc;
use std::cell::RefCell;
pub trait FontContextHandleMethods {
@ -23,16 +24,16 @@ pub trait FontContextHandleMethods {
}
pub struct FontContext {
instance_cache: LRUCache<FontDescriptor, RcMut<Font>>,
instance_cache: LRUCache<FontDescriptor, Rc<RefCell<Font>>>,
font_list: Option<FontList>, // only needed by layout
group_cache: LRUCache<SpecifiedFontStyle, RcMut<FontGroup>>,
group_cache: LRUCache<SpecifiedFontStyle, Rc<RefCell<FontGroup>>>,
handle: FontContextHandle,
backend: BackendType,
generic_fonts: HashMap<~str,~str>,
profiler_chan: ProfilerChan,
}
impl<'self> FontContext {
impl FontContext {
pub fn new(backend: BackendType,
needs_font_list: bool,
profiler_chan: ProfilerChan)
@ -61,11 +62,8 @@ impl<'self> FontContext {
}
}
fn get_font_list(&'self self) -> &'self FontList {
self.font_list.get_ref()
}
pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> RcMut<FontGroup> {
pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle)
-> Rc<RefCell<FontGroup>> {
match self.group_cache.find(style) {
Some(fg) => {
debug!("font group cache hit");
@ -80,7 +78,8 @@ impl<'self> FontContext {
}
}
pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor)
-> Result<Rc<RefCell<Font>>, ()> {
match self.instance_cache.find(desc) {
Some(f) => {
debug!("font cache hit");
@ -107,7 +106,7 @@ impl<'self> FontContext {
}
}
fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> RcMut<FontGroup> {
fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> Rc<RefCell<FontGroup>> {
let mut fonts = ~[];
debug!("(create font group) --- starting ---");
@ -140,8 +139,7 @@ impl<'self> FontContext {
Some(ref result) => {
found = true;
let instance = self.get_font_by_descriptor(result);
for font in instance.iter() { fonts.push(font.clone()); }
instance.map(|font| fonts.push(font.clone()));
},
_ => {}
}
@ -179,10 +177,7 @@ impl<'self> FontContext {
match font_desc {
Some(ref fd) => {
let instance = self.get_font_by_descriptor(fd);
for font in instance.iter() {
fonts.push(font.clone());
}
instance.map(|font| fonts.push(font.clone()));
},
None => { }
};
@ -194,22 +189,28 @@ impl<'self> FontContext {
debug!("(create font group) --- finished ---");
unsafe { RcMut::new_unchecked(FontGroup::new(style.families.clone(), &used_style, fonts)) }
unsafe {
Rc::new_unchecked(
RefCell::new(
FontGroup::new(style.families.to_owned(), &used_style, fonts)))
}
}
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> {
return match &desc.selector {
// TODO(Issue #174): implement by-platform-name font selectors.
&SelectorPlatformIdentifier(ref identifier) => {
let result_handle = self.handle.create_font_from_identifier((*identifier).clone(),
desc.style.clone());
do result_handle.and_then |handle| {
Ok(RcMut::new(Font::new_from_adopted_handle(self,
handle,
&desc.style,
self.backend,
self.profiler_chan.clone())))
}
result_handle.and_then(|handle| {
Ok(
Rc::from_mut(
RefCell::new(
Font::new_from_adopted_handle(self,
handle,
&desc.style,
self.backend))))
})
}
};
}

View file

@ -29,7 +29,7 @@ pub struct FontList {
prof_chan: ProfilerChan,
}
impl<'self> FontList {
impl FontList {
pub fn new(fctx: &FontContextHandle,
prof_chan: ProfilerChan)
-> FontList {
@ -48,20 +48,20 @@ impl<'self> FontList {
// changed. Does OSX have a notification for this event?
//
// Should font families with entries be invalidated/refreshed too?
do profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone()) {
profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone(), || {
self.family_map = self.handle.get_available_families();
}
});
}
pub fn find_font_in_family(&'self mut self,
family_name: &~str,
style: &SpecifiedFontStyle) -> Option<&'self FontEntry> {
pub fn find_font_in_family<'a>(&'a mut self,
family_name: &~str,
style: &SpecifiedFontStyle) -> Option<&'a FontEntry> {
// TODO(Issue #188): look up localized font family names if canonical name not found
// look up canonical name
if self.family_map.contains_key(family_name) {
//FIXME call twice!(ksh8281)
debug!("FontList: Found font family with name={:s}", family_name.to_str());
let s: &'self mut FontFamily = self.family_map.get_mut(family_name);
let s: &'a mut FontFamily = self.family_map.get_mut(family_name);
// TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
// if such family exists, try to match style to a font
let result = s.find_font_for_style(&mut self.handle, style);
@ -82,13 +82,13 @@ impl<'self> FontList {
}
}
// Holds a specific font family, and the various
pub struct FontFamily<'self> {
// Holds a specific font family, and the various
pub struct FontFamily {
family_name: ~str,
entries: ~[FontEntry],
}
impl<'self> FontFamily {
impl FontFamily {
pub fn new(family_name: &str) -> FontFamily {
FontFamily {
family_name: family_name.to_str(),
@ -104,8 +104,8 @@ impl<'self> FontFamily {
assert!(self.entries.len() > 0)
}
pub fn find_font_for_style(&'self mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
-> Option<&'self FontEntry> {
pub fn find_font_for_style<'a>(&'a mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
-> Option<&'a FontEntry> {
self.load_family_variations(list);
// TODO(Issue #189): optimize lookup for

View file

@ -2,10 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[link(name = "gfx",
vers = "0.1",
uuid = "0106bb54-6ea9-45bf-a39e-a738621f15e5",
url = "http://servo.org/")];
#[crate_id = "github.com/mozilla/servo#gfx:0.1"];
#[crate_type = "lib"];
#[feature(globs, managed_boxes, macro_rules)];
@ -16,10 +13,10 @@ extern mod geom;
extern mod layers;
extern mod stb_image;
extern mod png;
extern mod servo_net (name = "net");
extern mod servo_util (name = "util");
extern mod servo_net = "net";
extern mod servo_util = "util";
extern mod style;
extern mod servo_msg (name = "msg");
extern mod servo_msg = "msg";
// Eventually we would like the shaper to be pluggable, as many operating systems have their own
// shapers. For now, however, this is a hard dependency.

View file

@ -113,9 +113,9 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
};
// if only flag is present, default to 5 second period
let profiler_period = do opt_match.opt_default("p", "5").map |period| {
let profiler_period = opt_match.opt_default("p", "5").map(|period| {
from_str(period).unwrap()
};
});
let cpu_painting = opt_match.opt_present("c");

View file

@ -41,7 +41,7 @@ pub struct FontTable {
}
impl FontTableMethods for FontTable {
fn with_buffer(&self, _blk: &fn(*u8, uint)) {
fn with_buffer(&self, _blk: |*u8, uint|) {
fail!()
}
}
@ -61,7 +61,6 @@ pub struct FontHandle {
#[unsafe_destructor]
impl Drop for FontHandle {
#[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.face.is_not_null());
unsafe {
@ -80,9 +79,7 @@ impl FontHandleMethods for FontHandle {
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
if ft_ctx.is_null() { return Err(()); }
let face_result = do buf.as_imm_buf |bytes: *u8, len: uint| {
create_face_from_buffer(ft_ctx, bytes, len, style.pt_size)
};
let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size);
// TODO: this could be more simply written as result::chain
// and moving buf into the struct ctor, but cant' move out of
@ -99,7 +96,6 @@ impl FontHandleMethods for FontHandle {
Err(()) => Err(())
};
#[fixed_stack_segment]
fn create_face_from_buffer(lib: FT_Library, cbuf: *u8, cbuflen: uint, pt_size: f64)
-> Result<FT_Face, ()> {
unsafe {
@ -129,14 +125,12 @@ impl FontHandleMethods for FontHandle {
fn family_name(&self) -> ~str {
unsafe { str::raw::from_c_str((*self.face).family_name) }
}
#[fixed_stack_segment]
fn face_name(&self) -> ~str {
unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) }
}
fn is_italic(&self) -> bool {
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
}
#[fixed_stack_segment]
fn boldness(&self) -> font_weight::T {
let default_weight = font_weight::Weight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
@ -179,7 +173,6 @@ impl FontHandleMethods for FontHandle {
}
}
#[fixed_stack_segment]
fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> {
assert!(self.face.is_not_null());
@ -194,7 +187,6 @@ impl FontHandleMethods for FontHandle {
}
}
#[fixed_stack_segment]
fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> {
assert!(self.face.is_not_null());
@ -216,7 +208,6 @@ impl FontHandleMethods for FontHandle {
}
}
#[fixed_stack_segment]
fn get_metrics(&self) -> FontMetrics {
/* TODO(Issue #76): complete me */
let face = self.get_face_rec();
@ -272,8 +263,7 @@ impl FontHandleMethods for FontHandle {
}
}
impl<'self> FontHandle {
#[fixed_stack_segment]
impl<'a> FontHandle {
fn set_char_size(face: FT_Face, pt_size: f64) -> Result<(), ()>{
let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
@ -286,7 +276,6 @@ impl<'self> FontHandle {
}
}
#[fixed_stack_segment]
pub fn new_from_file(fctx: &FontContextHandle, file: &str,
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
unsafe {
@ -295,10 +284,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do file.to_c_str().with_ref |file_str| {
file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
});
if face.is_null() {
return Err(());
}
@ -314,7 +303,6 @@ impl<'self> FontHandle {
}
}
#[fixed_stack_segment]
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
-> Result<FontHandle, ()> {
unsafe {
@ -323,10 +311,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do file.to_c_str().with_ref |file_str| {
file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
});
if face.is_null() {
return Err(());
}
@ -339,7 +327,7 @@ impl<'self> FontHandle {
}
}
fn get_face_rec(&'self self) -> &'self FT_FaceRec {
fn get_face_rec(&'a self) -> &'a FT_FaceRec {
unsafe {
&(*self.face)
}

View file

@ -24,7 +24,6 @@ pub struct FontContextHandle {
}
impl Drop for FreeTypeLibraryHandle {
#[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.ctx.is_not_null());
unsafe { FT_Done_FreeType(self.ctx) };
@ -32,7 +31,6 @@ impl Drop for FreeTypeLibraryHandle {
}
impl FontContextHandle {
#[fixed_stack_segment]
pub fn new() -> FontContextHandle {
unsafe {
let ctx: FT_Library = ptr::null();
@ -49,10 +47,10 @@ impl FontContextHandleMethods for FontContextHandle {
fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle)
-> Result<FontHandle, ()> {
debug!("Creating font handle for {:s}", name);
do path_from_identifier(name, &style).and_then |file_name| {
path_from_identifier(name, &style).and_then(|file_name| {
debug!("Opening font face {:s}", file_name);
FontHandle::new_from_file(self, file_name.to_owned(), &style)
}
})
}
}

View file

@ -40,7 +40,6 @@ impl FontListHandle {
FontListHandle { fctx: fctx.clone() }
}
#[fixed_stack_segment]
pub fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = HashMap::new();
unsafe {
@ -50,7 +49,7 @@ impl FontListHandle {
let font = (*fontSet).fonts.offset(i);
let family: *FcChar8 = ptr::null();
let mut v: c_int = 0;
do "family".to_c_str().with_ref |FC_FAMILY| {
"family".to_c_str().with_ref(|FC_FAMILY| {
while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch {
let family_name = str::raw::from_c_str(family as *c_char);
debug!("Creating new FontFamily for family: {:s}", family_name);
@ -58,13 +57,12 @@ impl FontListHandle {
family_map.insert(family_name, new_family);
v += 1;
}
}
});
}
}
return family_map;
}
#[fixed_stack_segment]
pub fn load_variations_for_family(&self, family: &mut FontFamily) {
debug!("getting variations for {:?}", family);
unsafe {
@ -73,22 +71,22 @@ impl FontListHandle {
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set);
let pattern = FcPatternCreate();
assert!(pattern.is_not_null());
do "family".to_c_str().with_ref |FC_FAMILY| {
do family.family_name.to_c_str().with_ref |family_name| {
"family".to_c_str().with_ref(|FC_FAMILY| {
family.family_name.to_c_str().with_ref(|family_name| {
let ok = FcPatternAddString(pattern, FC_FAMILY, family_name as *FcChar8);
assert!(ok != 0);
}
}
});
});
let object_set = FcObjectSetCreate();
assert!(object_set.is_not_null());
do "file".to_c_str().with_ref |FC_FILE| {
"file".to_c_str().with_ref(|FC_FILE| {
FcObjectSetAdd(object_set, FC_FILE);
}
do "index".to_c_str().with_ref |FC_INDEX| {
});
"index".to_c_str().with_ref(|FC_INDEX| {
FcObjectSetAdd(object_set, FC_INDEX);
}
});
let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set);
@ -96,22 +94,22 @@ impl FontListHandle {
for i in range(0, (*matches).nfont as int) {
let font = (*matches).fonts.offset(i);
let file = do "file".to_c_str().with_ref |FC_FILE| {
let file = "file".to_c_str().with_ref(|FC_FILE| {
let file: *FcChar8 = ptr::null();
if FcPatternGetString(*font, FC_FILE, 0, &file) == FcResultMatch {
str::raw::from_c_str(file as *libc::c_char)
} else {
fail!();
}
};
let index = do "index".to_c_str().with_ref |FC_INDEX| {
});
let index = "index".to_c_str().with_ref(|FC_INDEX| {
let index: libc::c_int = 0;
if FcPatternGetInteger(*font, FC_INDEX, 0, &index) == FcResultMatch {
index
} else {
fail!();
}
};
});
debug!("variation file: {}", file);
debug!("variation index: {}", index);
@ -141,7 +139,6 @@ struct AutoPattern {
}
impl Drop for AutoPattern {
#[fixed_stack_segment]
fn drop(&mut self) {
unsafe {
FcPatternDestroy(self.pattern);
@ -149,17 +146,16 @@ impl Drop for AutoPattern {
}
}
#[fixed_stack_segment]
pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, ()> {
unsafe {
let config = FcConfigGetCurrent();
let wrapper = AutoPattern { pattern: FcPatternCreate() };
let pattern = wrapper.pattern;
let res = do "family".to_c_str().with_ref |FC_FAMILY| {
do name.to_c_str().with_ref |family| {
let res = "family".to_c_str().with_ref(|FC_FAMILY| {
name.to_c_str().with_ref(|family| {
FcPatternAddString(pattern, FC_FAMILY, family as *FcChar8)
}
};
})
});
if res != 1 {
debug!("adding family to pattern failed");
return Err(());
@ -168,18 +164,18 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
match style.style {
font_style::normal => (),
font_style::italic => {
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
};
});
if res != 1 {
debug!("adding slant to pattern failed");
return Err(());
}
},
font_style::oblique => {
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
};
});
if res != 1 {
debug!("adding slant(oblique) to pattern failed");
return Err(());
@ -188,9 +184,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
if style.weight.is_bold() {
let res = do "weight".to_c_str().with_ref |FC_WEIGHT| {
let res = "weight".to_c_str().with_ref(|FC_WEIGHT| {
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD)
};
});
if res != 1 {
debug!("adding weight to pattern failed");
return Err(());
@ -211,9 +207,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
let file: *FcChar8 = ptr::null();
let res = do "file".to_c_str().with_ref |FC_FILE| {
let res = "file".to_c_str().with_ref(|FC_FILE| {
FcPatternGetString(result_pattern, FC_FILE, 0, &file)
};
});
if res != FcResultMatch {
debug!("getting filename for font failed");
return Err(());

View file

@ -41,7 +41,7 @@ pub struct FontTable {
}
impl FontTableMethods for FontTable {
fn with_buffer(&self, _blk: &fn(*u8, uint)) {
fn with_buffer(&self, _blk: |*u8, uint|) {
fail!()
}
}
@ -61,7 +61,6 @@ pub struct FontHandle {
#[unsafe_destructor]
impl Drop for FontHandle {
#[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.face.is_not_null());
unsafe {
@ -80,9 +79,7 @@ impl FontHandleMethods for FontHandle {
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
if ft_ctx.is_null() { return Err(()); }
let face_result = do buf.as_imm_buf |bytes: *u8, len: uint| {
create_face_from_buffer(ft_ctx, bytes, len, style.pt_size)
};
let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size);
// TODO: this could be more simply written as result::chain
// and moving buf into the struct ctor, but cant' move out of
@ -99,7 +96,6 @@ impl FontHandleMethods for FontHandle {
Err(()) => Err(())
};
#[fixed_stack_segment]
fn create_face_from_buffer(lib: FT_Library, cbuf: *u8, cbuflen: uint, pt_size: f64)
-> Result<FT_Face, ()> {
unsafe {
@ -129,14 +125,12 @@ impl FontHandleMethods for FontHandle {
fn family_name(&self) -> ~str {
unsafe { str::raw::from_c_str((*self.face).family_name) }
}
#[fixed_stack_segment]
fn face_name(&self) -> ~str {
unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) }
}
fn is_italic(&self) -> bool {
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
}
#[fixed_stack_segment]
fn boldness(&self) -> font_weight::T {
let default_weight = font_weight::Weight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
@ -179,7 +173,6 @@ impl FontHandleMethods for FontHandle {
}
}
#[fixed_stack_segment]
fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> {
assert!(self.face.is_not_null());
@ -194,7 +187,6 @@ impl FontHandleMethods for FontHandle {
}
}
#[fixed_stack_segment]
fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> {
assert!(self.face.is_not_null());
@ -216,7 +208,6 @@ impl FontHandleMethods for FontHandle {
}
}
#[fixed_stack_segment]
fn get_metrics(&self) -> FontMetrics {
/* TODO(Issue #76): complete me */
let face = self.get_face_rec();
@ -272,8 +263,7 @@ impl FontHandleMethods for FontHandle {
}
}
impl<'self> FontHandle {
#[fixed_stack_segment]
impl<'a> FontHandle {
fn set_char_size(face: FT_Face, pt_size: f64) -> Result<(), ()>{
let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
@ -286,7 +276,6 @@ impl<'self> FontHandle {
}
}
#[fixed_stack_segment]
pub fn new_from_file(fctx: &FontContextHandle, file: &str,
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
unsafe {
@ -295,10 +284,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do file.to_c_str().with_ref |file_str| {
file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
});
if face.is_null() {
return Err(());
}
@ -314,7 +303,6 @@ impl<'self> FontHandle {
}
}
#[fixed_stack_segment]
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
-> Result<FontHandle, ()> {
unsafe {
@ -323,10 +311,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
do file.to_c_str().with_ref |file_str| {
file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
}
});
if face.is_null() {
return Err(());
}
@ -339,7 +327,7 @@ impl<'self> FontHandle {
}
}
fn get_face_rec(&'self self) -> &'self FT_FaceRec {
fn get_face_rec(&'a self) -> &'a FT_FaceRec {
unsafe {
&(*self.face)
}

View file

@ -24,7 +24,6 @@ pub struct FontContextHandle {
}
impl Drop for FreeTypeLibraryHandle {
#[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.ctx.is_not_null());
unsafe { FT_Done_FreeType(self.ctx) };
@ -32,7 +31,6 @@ impl Drop for FreeTypeLibraryHandle {
}
impl FontContextHandle {
#[fixed_stack_segment]
pub fn new() -> FontContextHandle {
unsafe {
let ctx: FT_Library = ptr::null();
@ -49,10 +47,10 @@ impl FontContextHandleMethods for FontContextHandle {
fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle)
-> Result<FontHandle, ()> {
debug!("Creating font handle for {:s}", name);
do path_from_identifier(name, &style).and_then |file_name| {
path_from_identifier(name, &style).and_then(|file_name| {
debug!("Opening font face {:s}", file_name);
FontHandle::new_from_file(self, file_name.to_owned(), &style)
}
})
}
}

View file

@ -40,7 +40,6 @@ impl FontListHandle {
FontListHandle { fctx: fctx.clone() }
}
#[fixed_stack_segment]
pub fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = HashMap::new();
unsafe {
@ -50,7 +49,7 @@ impl FontListHandle {
let font = (*fontSet).fonts.offset(i);
let family: *FcChar8 = ptr::null();
let mut v: c_int = 0;
do "family".to_c_str().with_ref |FC_FAMILY| {
"family".to_c_str().with_ref(|FC_FAMILY| {
while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch {
let family_name = str::raw::from_c_str(family as *c_char);
debug!("Creating new FontFamily for family: {:s}", family_name);
@ -58,13 +57,12 @@ impl FontListHandle {
family_map.insert(family_name, new_family);
v += 1;
}
}
});
}
}
return family_map;
}
#[fixed_stack_segment]
pub fn load_variations_for_family(&self, family: &mut FontFamily) {
debug!("getting variations for {:?}", family);
unsafe {
@ -73,22 +71,22 @@ impl FontListHandle {
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set);
let pattern = FcPatternCreate();
assert!(pattern.is_not_null());
do "family".to_c_str().with_ref |FC_FAMILY| {
do family.family_name.to_c_str().with_ref |family_name| {
"family".to_c_str().with_ref(|FC_FAMILY| {
family.family_name.to_c_str().with_ref(|family_name| {
let ok = FcPatternAddString(pattern, FC_FAMILY, family_name as *FcChar8);
assert!(ok != 0);
}
}
});
});
let object_set = FcObjectSetCreate();
assert!(object_set.is_not_null());
do "file".to_c_str().with_ref |FC_FILE| {
"file".to_c_str().with_ref(|FC_FILE| {
FcObjectSetAdd(object_set, FC_FILE);
}
do "index".to_c_str().with_ref |FC_INDEX| {
});
"index".to_c_str().with_ref(|FC_INDEX| {
FcObjectSetAdd(object_set, FC_INDEX);
}
});
let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set);
@ -96,22 +94,22 @@ impl FontListHandle {
for i in range(0, (*matches).nfont as int) {
let font = (*matches).fonts.offset(i);
let file = do "file".to_c_str().with_ref |FC_FILE| {
let file = "file".to_c_str().with_ref(|FC_FILE| {
let file: *FcChar8 = ptr::null();
if FcPatternGetString(*font, FC_FILE, 0, &file) == FcResultMatch {
str::raw::from_c_str(file as *libc::c_char)
} else {
fail!();
}
};
let index = do "index".to_c_str().with_ref |FC_INDEX| {
});
let index = "index".to_c_str().with_ref(|FC_INDEX| {
let index: libc::c_int = 0;
if FcPatternGetInteger(*font, FC_INDEX, 0, &index) == FcResultMatch {
index
} else {
fail!();
}
};
});
debug!("variation file: {}", file);
debug!("variation index: {}", index);
@ -141,7 +139,6 @@ struct AutoPattern {
}
impl Drop for AutoPattern {
#[fixed_stack_segment]
fn drop(&mut self) {
unsafe {
FcPatternDestroy(self.pattern);
@ -149,17 +146,16 @@ impl Drop for AutoPattern {
}
}
#[fixed_stack_segment]
pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, ()> {
unsafe {
let config = FcConfigGetCurrent();
let wrapper = AutoPattern { pattern: FcPatternCreate() };
let pattern = wrapper.pattern;
let res = do "family".to_c_str().with_ref |FC_FAMILY| {
do name.to_c_str().with_ref |family| {
let res = "family".to_c_str().with_ref(|FC_FAMILY| {
name.to_c_str().with_ref(|family| {
FcPatternAddString(pattern, FC_FAMILY, family as *FcChar8)
}
};
})
});
if res != 1 {
debug!("adding family to pattern failed");
return Err(());
@ -168,18 +164,18 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
match style.style {
font_style::normal => (),
font_style::italic => {
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
};
});
if res != 1 {
debug!("adding slant to pattern failed");
return Err(());
}
},
font_style::oblique => {
let res = do "slant".to_c_str().with_ref |FC_SLANT| {
let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
};
});
if res != 1 {
debug!("adding slant(oblique) to pattern failed");
return Err(());
@ -188,9 +184,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
if style.weight.is_bold() {
let res = do "weight".to_c_str().with_ref |FC_WEIGHT| {
let res = "weight".to_c_str().with_ref(|FC_WEIGHT| {
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD)
};
});
if res != 1 {
debug!("adding weight to pattern failed");
return Err(());
@ -211,9 +207,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
let file: *FcChar8 = ptr::null();
let res = do "file".to_c_str().with_ref |FC_FILE| {
let res = "file".to_c_str().with_ref(|FC_FILE| {
FcPatternGetString(result_pattern, FC_FILE, 0, &file)
};
});
if res != FcResultMatch {
debug!("getting filename for font failed");
return Err(());

View file

@ -29,7 +29,6 @@ use core_text::font_descriptor::{kCTFontDefaultOrientation};
use core_text;
use std::ptr;
use std::vec;
pub struct FontTable {
data: CFData,
@ -47,8 +46,8 @@ impl FontTable {
}
impl FontTableMethods for FontTable {
fn with_buffer(&self, blk: &fn(*u8, uint)) {
blk(vec::raw::to_ptr(self.data.bytes()), self.data.len() as uint);
fn with_buffer(&self, blk: |*u8, uint|) {
blk(self.data.bytes().as_ptr(), self.data.len() as uint);
}
}
@ -185,9 +184,9 @@ impl FontHandleMethods for FontHandle {
fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
let result: Option<CFData> = self.ctfont.get_font_table(tag);
do result.and_then |data| {
result.and_then(|data| {
Some(FontTable::wrap(data))
}
})
}
fn face_identifier(&self) -> ~str {

View file

@ -27,8 +27,8 @@ impl FontContextHandleMethods for FontContextHandle {
style: UsedFontStyle)
-> Result<FontHandle, ()> {
let ctfont_result = core_text::font::new_from_name(name, style.pt_size);
do ctfont_result.and_then |ctfont| {
ctfont_result.and_then(|ctfont| {
FontHandle::new_from_CTFont(self, ctfont)
}
})
}
}

View file

@ -18,14 +18,13 @@ use geom::side_offsets::SideOffsets2D;
use servo_net::image::base::Image;
use png::{RGBA8, K8, KA8};
use servo_util::geometry::Au;
use std::vec;
use std::libc::types::common::c99::uint16_t;
use std::libc::size_t;
pub struct RenderContext<'self> {
draw_target: &'self DrawTarget,
font_ctx: &'self mut ~FontContext,
opts: &'self Opts,
pub struct RenderContext<'a> {
draw_target: &'a DrawTarget,
font_ctx: &'a mut ~FontContext,
opts: &'a Opts,
/// The rectangle that this context encompasses in page coordinates.
page_rect: Rect<f32>,
/// The rectangle that this context encompasses in screen coordinates (pixels).
@ -39,8 +38,8 @@ enum Direction {
Bottom
}
impl<'self> RenderContext<'self> {
pub fn get_draw_target(&self) -> &'self DrawTarget {
impl<'a> RenderContext<'a> {
pub fn get_draw_target(&self) -> &'a DrawTarget {
self.draw_target
}
@ -167,7 +166,7 @@ impl<'self> RenderContext<'self> {
stroke_opts.line_width = border_width;
dash[0] = border_width * 3 as AzFloat;
dash[1] = border_width * 3 as AzFloat;
stroke_opts.mDashPattern = vec::raw::to_ptr(dash);
stroke_opts.mDashPattern = dash.as_ptr();
stroke_opts.mDashLength = dash.len() as size_t;
let (start, end) = match direction {

View file

@ -20,7 +20,6 @@ use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
use std::comm::{Chan, Port, SharedChan};
use std::task::spawn_with;
use extra::arc::Arc;
use buffer_map::BufferMap;
@ -63,24 +62,32 @@ pub fn BufferRequest(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferReq
// FIXME(rust#9155): this should be a newtype struct, but
// generic newtypes ICE when compiled cross-crate
#[deriving(Clone)]
pub struct RenderChan<T> {
chan: SharedChan<Msg<T>>,
}
impl<T: Send> RenderChan<T> {
pub fn new(chan: Chan<Msg<T>>) -> RenderChan<T> {
impl<T: Send> Clone for RenderChan<T> {
fn clone(&self) -> RenderChan<T> {
RenderChan {
chan: SharedChan::new(chan),
chan: self.chan.clone(),
}
}
}
impl<T: Send> GenericChan<Msg<T>> for RenderChan<T> {
fn send(&self, msg: Msg<T>) {
impl<T: Send> RenderChan<T> {
pub fn new() -> (Port<Msg<T>>, RenderChan<T>) {
let (port, chan) = SharedChan::new();
let render_chan = RenderChan {
chan: chan,
};
(port, render_chan)
}
pub fn send(&self, msg: Msg<T>) {
assert!(self.try_send(msg), "RenderChan.send: render port closed")
}
}
impl<T: Send> GenericSmartChan<Msg<T>> for RenderChan<T> {
fn try_send(&self, msg: Msg<T>) -> bool {
pub fn try_send(&self, msg: Msg<T>) -> bool {
self.chan.try_send(msg)
}
}
@ -138,9 +145,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
opts: Opts,
profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) {
do spawn_with((port, compositor, constellation_chan, opts, profiler_chan, shutdown_chan))
|(port, compositor, constellation_chan, opts, profiler_chan, shutdown_chan)| {
spawn(proc() {
{ // Ensures RenderTask and graphics context are destroyed before shutdown msg
let native_graphics_context = compositor.get_graphics_metadata().map(
|md| NativePaintingGraphicsContext::from_metadata(&md));
@ -153,8 +158,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
compositor: compositor,
constellation_chan: constellation_chan,
font_ctx: ~FontContext::new(opts.render_backend.clone(),
false,
profiler_chan.clone()),
false,
profiler_chan.clone()),
opts: opts,
profiler_chan: profiler_chan,
@ -176,13 +181,12 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
render_task.start();
// Destroy all the buffers.
render_task.native_graphics_context.as_ref().map(|ctx|
render_task.buffer_map.clear(ctx)
);
render_task.native_graphics_context.as_ref().map(
|ctx| render_task.buffer_map.clear(ctx));
}
shutdown_chan.send(());
}
});
}
fn start(&mut self) {
@ -243,12 +247,12 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
}
self.compositor.set_render_state(RenderingRenderState);
do time::profile(time::RenderingCategory, self.profiler_chan.clone()) {
time::profile(time::RenderingCategory, self.profiler_chan.clone(), || {
// FIXME: Try not to create a new array here.
let mut new_buffers = ~[];
// Divide up the layer into tiles.
do time::profile(time::RenderingPrepBuffCategory, self.profiler_chan.clone()) {
time::profile(time::RenderingPrepBuffCategory, self.profiler_chan.clone(), || {
for tile in tiles.iter() {
let width = tile.screen_rect.size.width;
let height = tile.screen_rect.size.height;
@ -293,10 +297,10 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
ctx.clear();
// Draw the display list.
do profile(time::RenderingDrawingCategory, self.profiler_chan.clone()) {
profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || {
render_layer.display_list.get().draw_into_context(&mut ctx);
ctx.draw_target.flush();
}
});
}
// Extract the texture from the draw target and place it into its slot in the
@ -335,11 +339,11 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
}
};
do draw_target.snapshot().get_data_surface().with_data |data| {
draw_target.snapshot().get_data_surface().with_data(|data| {
buffer.native_surface.upload(native_graphics_context!(self), data);
debug!("RENDERER uploading to native surface {:d}",
buffer.native_surface.get_id() as int);
}
});
buffer
}
@ -367,7 +371,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
new_buffers.push(buffer);
}
}
});
let layer_buffer_set = ~LayerBufferSet {
buffers: new_buffers,
@ -380,7 +384,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
self.constellation_chan.send(RendererReadyMsg(self.id));
}
self.compositor.set_render_state(IdleRenderState);
}
})
}
}

View file

@ -14,7 +14,6 @@ use std::vec;
use std::util;
use std::iter;
use geom::point::Point2D;
use extra::sort;
/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly.
///
@ -149,8 +148,8 @@ static FLAG_NOT_LIGATURE_GROUP_START: u32 = 0x00000004;
static FLAG_CHAR_IS_TAB: u32 = 0x00000008;
static FLAG_CHAR_IS_NEWLINE: u32 = 0x00000010;
static FLAG_CHAR_IS_LOW_SURROGATE: u32 = 0x00000020;
static CHAR_IDENTITY_FLAGS_MASK: u32 = 0x00000038;
//static FLAG_CHAR_IS_LOW_SURROGATE: u32 = 0x00000020;
//static CHAR_IDENTITY_FLAGS_MASK: u32 = 0x00000038;
fn is_simple_glyph_id(glyphId: GlyphIndex) -> bool {
((glyphId as u32) & GLYPH_ID_MASK) == glyphId
@ -176,10 +175,6 @@ impl GlyphEntry {
self.value & GLYPH_ID_MASK
}
fn offset(&self) -> Point2D<Au> {
Point2D(Au(0), Au(0))
}
fn is_ligature_start(&self) -> bool {
self.has_flag(!FLAG_NOT_LIGATURE_GROUP_START)
}
@ -312,7 +307,7 @@ struct DetailedGlyphStore {
lookup_is_sorted: bool,
}
impl<'self> DetailedGlyphStore {
impl<'a> DetailedGlyphStore {
fn new() -> DetailedGlyphStore {
DetailedGlyphStore {
detail_buffer: ~[], // TODO: default size?
@ -345,8 +340,8 @@ impl<'self> DetailedGlyphStore {
self.lookup_is_sorted = false;
}
fn get_detailed_glyphs_for_entry(&'self self, entry_offset: uint, count: u16)
-> &'self [DetailedGlyph] {
fn get_detailed_glyphs_for_entry(&'a self, entry_offset: uint, count: u16)
-> &'a [DetailedGlyph] {
debug!("Requesting detailed glyphs[n={:u}] for entry[off={:u}]", count as uint, entry_offset);
// FIXME: Is this right? --pcwalton
@ -375,10 +370,10 @@ impl<'self> DetailedGlyphStore {
}
}
fn get_detailed_glyph_with_index(&'self self,
fn get_detailed_glyph_with_index(&'a self,
entry_offset: uint,
detail_offset: u16)
-> &'self DetailedGlyph {
-> &'a DetailedGlyph {
assert!((detail_offset as uint) <= self.detail_buffer.len());
assert!(self.lookup_is_sorted);
@ -411,7 +406,13 @@ impl<'self> DetailedGlyphStore {
let mut unsorted_records: ~[DetailedGlyphRecord] = ~[];
util::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records;
sort::quick_sort3(mut_records);
mut_records.sort_by(|a, b| {
if a < b {
Less
} else {
Greater
}
});
let mut sorted_records = mut_records;
util::swap(&mut self.detail_lookup, &mut sorted_records);
@ -458,12 +459,12 @@ impl GlyphData {
// through glyphs (either for a particular TextRun offset, or all glyphs).
// Rather than eagerly assembling and copying glyph data, it only retrieves
// values as they are needed from the GlyphStore, using provided offsets.
enum GlyphInfo<'self> {
SimpleGlyphInfo(&'self GlyphStore, uint),
DetailGlyphInfo(&'self GlyphStore, uint, u16)
enum GlyphInfo<'a> {
SimpleGlyphInfo(&'a GlyphStore, uint),
DetailGlyphInfo(&'a GlyphStore, uint, u16)
}
impl<'self> GlyphInfo<'self> {
impl<'a> GlyphInfo<'a> {
pub fn index(self) -> GlyphIndex {
match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].index(),
@ -492,20 +493,6 @@ impl<'self> GlyphInfo<'self> {
}
}
}
pub fn is_ligature_start(self) -> bool {
match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_ligature_start(),
DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_ligature_start()
}
}
pub fn is_cluster_start(self) -> bool {
match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_cluster_start(),
DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_cluster_start()
}
}
}
// Public data structure and API for storing and retrieving glyph data
@ -519,7 +506,7 @@ pub struct GlyphStore {
is_whitespace: bool,
}
impl<'self> GlyphStore {
impl<'a> GlyphStore {
// Initializes the glyph store, but doesn't actually shape anything.
// Use the set_glyph, set_glyphs() methods to store glyph data.
pub fn new(length: uint, is_whitespace: bool) -> GlyphStore {
@ -606,12 +593,12 @@ impl<'self> GlyphStore {
self.entry_buffer[i] = entry;
}
pub fn iter_glyphs_for_char_index(&'self self, i: uint) -> GlyphIterator<'self> {
pub fn iter_glyphs_for_char_index(&'a self, i: uint) -> GlyphIterator<'a> {
self.iter_glyphs_for_char_range(&Range::new(i, 1))
}
#[inline]
pub fn iter_glyphs_for_char_range(&'self self, rang: &Range) -> GlyphIterator<'self> {
pub fn iter_glyphs_for_char_range(&'a self, rang: &Range) -> GlyphIterator<'a> {
if rang.begin() >= self.entry_buffer.len() {
fail!("iter_glyphs_for_range: range.begin beyond length!");
}
@ -684,17 +671,17 @@ impl<'self> GlyphStore {
}
}
pub struct GlyphIterator<'self> {
priv store: &'self GlyphStore,
pub struct GlyphIterator<'a> {
priv store: &'a GlyphStore,
priv char_index: uint,
priv char_range: iter::Range<uint>,
priv glyph_range: Option<iter::Range<uint>>,
}
impl<'self> GlyphIterator<'self> {
impl<'a> GlyphIterator<'a> {
// Slow path when there is a glyph range.
#[inline(never)]
fn next_glyph_range(&mut self) -> Option<(uint, GlyphInfo<'self>)> {
fn next_glyph_range(&mut self) -> Option<(uint, GlyphInfo<'a>)> {
match self.glyph_range.get_mut_ref().next() {
Some(j) => Some((self.char_index,
DetailGlyphInfo(self.store, self.char_index, j as u16))),
@ -709,14 +696,14 @@ impl<'self> GlyphIterator<'self> {
// Slow path when there is a complex glyph.
#[inline(never)]
fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: uint)
-> Option<(uint, GlyphInfo<'self>)> {
-> Option<(uint, GlyphInfo<'a>)> {
let glyphs = self.store.detail_store.get_detailed_glyphs_for_entry(i, entry.glyph_count());
self.glyph_range = Some(range(0, glyphs.len()));
self.next()
}
}
impl<'self> Iterator<(uint, GlyphInfo<'self>)> for GlyphIterator<'self> {
impl<'a> Iterator<(uint, GlyphInfo<'a>)> for GlyphIterator<'a> {
// I tried to start with something simpler and apply FlatMap, but the
// inability to store free variables in the FlatMap struct was problematic.
//
@ -724,7 +711,7 @@ impl<'self> Iterator<(uint, GlyphInfo<'self>)> for GlyphIterator<'self> {
// slow paths, which should not be inlined, are `next_glyph_range()` and
// `next_complex_glyph()`.
#[inline(always)]
fn next(&mut self) -> Option<(uint, GlyphInfo<'self>)> {
fn next(&mut self) -> Option<(uint, GlyphInfo<'a>)> {
// Would use 'match' here but it borrows contents in a way that
// interferes with mutation.
if self.glyph_range.is_some() {

View file

@ -10,15 +10,14 @@ use platform::font::FontTable;
use text::glyph::{GlyphStore, GlyphIndex, GlyphData};
use text::shaping::ShaperMethods;
use servo_util::range::Range;
use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int};
use text::util::{float_to_fixed, fixed_to_float};
use std::cast::transmute;
use std::char;
use std::libc::{c_uint, c_int, c_void, c_char};
use std::ptr;
use std::ptr::null;
use std::uint;
use std::util::ignore;
use std::num;
use std::vec;
use geom::Point2D;
use harfbuzz::{hb_blob_create, hb_face_create_for_tables};
@ -63,7 +62,6 @@ pub struct ShapedGlyphEntry {
}
impl ShapedGlyphData {
#[fixed_stack_segment]
pub fn new(buffer: *hb_buffer_t) -> ShapedGlyphData {
unsafe {
let glyph_count = 0;
@ -143,7 +141,6 @@ pub struct Shaper {
#[unsafe_destructor]
impl Drop for Shaper {
#[fixed_stack_segment]
fn drop(&mut self) {
unsafe {
assert!(self.hb_face.is_not_null());
@ -159,7 +156,6 @@ impl Drop for Shaper {
}
impl Shaper {
#[fixed_stack_segment]
pub fn new(font: &mut Font) -> Shaper {
unsafe {
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
@ -200,29 +196,22 @@ impl Shaper {
fn fixed_to_float(i: hb_position_t) -> f64 {
fixed_to_float(16, i)
}
fn fixed_to_rounded_int(f: hb_position_t) -> int {
fixed_to_rounded_int(16, f)
}
}
impl ShaperMethods for Shaper {
/// Calculate the layout metrics associated with the given text when rendered in a specific
/// font.
#[fixed_stack_segment]
fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) {
unsafe {
let hb_buffer: *hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
// Using as_imm_buf because it never does a copy - we don't need the trailing null
do text.as_imm_buf |ctext: *u8, _: uint| {
hb_buffer_add_utf8(hb_buffer,
ctext as *c_char,
text.len() as c_int,
0,
text.len() as c_int);
}
hb_buffer_add_utf8(hb_buffer,
text.as_ptr() as *c_char,
text.len() as c_int,
0,
text.len() as c_int);
hb_shape(self.hb_font, hb_buffer, null(), 0);
self.save_glyph_results(text, glyphs, hb_buffer);
@ -261,7 +250,7 @@ impl Shaper {
byteToGlyph = vec::from_elem(byte_max, NO_GLYPH);
} else {
byteToGlyph = vec::from_elem(byte_max, CONTINUATION_BYTE);
for (i, _) in text.char_offset_iter() {
for (i, _) in text.char_indices() {
byteToGlyph[i] = NO_GLYPH;
}
}
@ -283,7 +272,7 @@ impl Shaper {
debug!("text: {:s}", text);
debug!("(char idx): char->(glyph index):");
for (i, ch) in text.char_offset_iter() {
for (i, ch) in text.char_indices() {
debug!("{:u}: {} --> {:d}", i, ch, byteToGlyph[i] as int);
}
@ -309,7 +298,7 @@ impl Shaper {
// any trailing chars that do not have associated glyphs.
while char_byte_span.end() < byte_max {
let range = text.char_range_at(char_byte_span.end());
ignore(range.ch);
drop(range.ch);
char_byte_span.extend_to(range.next);
debug!("Processing char byte span: off={:u}, len={:u} for glyph idx={:u}",
@ -320,7 +309,7 @@ impl Shaper {
debug!("Extending char byte span to include byte offset={:u} with no associated \
glyph", char_byte_span.end());
let range = text.char_range_at(char_byte_span.end());
ignore(range.ch);
drop(range.ch);
char_byte_span.extend_to(range.next);
}
@ -329,7 +318,7 @@ impl Shaper {
let mut max_glyph_idx = glyph_span.end();
for i in char_byte_span.eachi() {
if byteToGlyph[i] > NO_GLYPH {
max_glyph_idx = uint::max(byteToGlyph[i] as uint + 1, max_glyph_idx);
max_glyph_idx = num::max(byteToGlyph[i] as uint + 1, max_glyph_idx);
}
}
@ -390,7 +379,7 @@ impl Shaper {
while covered_byte_span.end() < byte_max
&& byteToGlyph[covered_byte_span.end()] == NO_GLYPH {
let range = text.char_range_at(covered_byte_span.end());
ignore(range.ch);
drop(range.ch);
covered_byte_span.extend_to(range.next);
}
@ -404,7 +393,7 @@ impl Shaper {
// clamp to end of text. (I don't think this will be necessary, but..)
let end = covered_byte_span.end(); // FIXME: borrow checker workaround
covered_byte_span.extend_to(uint::min(end, byte_max));
covered_byte_span.extend_to(num::min(end, byte_max));
// fast path: 1-to-1 mapping of single char and single glyph.
if glyph_span.length() == 1 {
@ -443,7 +432,7 @@ impl Shaper {
let mut i = covered_byte_span.begin();
loop {
let range = text.char_range_at(i);
ignore(range.ch);
drop(range.ch);
i = range.next;
if i >= covered_byte_span.end() { break; }
char_idx += 1;
@ -514,14 +503,14 @@ extern fn get_font_table_func(_: *hb_face_t, tag: hb_tag_t, user_data: *c_void)
let skinny_font_table_ptr: *FontTable = font_table; // private context
let mut blob: *hb_blob_t = null();
do (*skinny_font_table_ptr).with_buffer |buf: *u8, len: uint| {
(*skinny_font_table_ptr).with_buffer(|buf: *u8, len: uint| {
// HarfBuzz calls `destroy_blob_func` when the buffer is no longer needed.
blob = hb_blob_create(buf as *c_char,
len as c_uint,
HB_MEMORY_MODE_READONLY,
transmute(skinny_font_table_ptr),
destroy_blob_func);
}
});
assert!(blob.is_not_null());
blob

View file

@ -22,16 +22,16 @@ pub struct TextRun {
glyphs: Arc<~[Arc<GlyphStore>]>,
}
pub struct SliceIterator<'self> {
priv glyph_iter: VecIterator<'self, Arc<GlyphStore>>,
pub struct SliceIterator<'a> {
priv glyph_iter: VecIterator<'a, Arc<GlyphStore>>,
priv range: Range,
priv offset: uint,
}
impl<'self> Iterator<(&'self GlyphStore, uint, Range)> for SliceIterator<'self> {
impl<'a> Iterator<(&'a GlyphStore, uint, Range)> for SliceIterator<'a> {
// inline(always) due to the inefficient rt failures messing up inline heuristics, I think.
#[inline(always)]
fn next(&mut self) -> Option<(&'self GlyphStore, uint, Range)> {
fn next(&mut self) -> Option<(&'a GlyphStore, uint, Range)> {
loop {
let slice_glyphs = self.glyph_iter.next();
if slice_glyphs.is_none() {
@ -52,13 +52,13 @@ impl<'self> Iterator<(&'self GlyphStore, uint, Range)> for SliceIterator<'self>
}
}
pub struct LineIterator<'self> {
pub struct LineIterator<'a> {
priv range: Range,
priv clump: Option<Range>,
priv slices: SliceIterator<'self>,
priv slices: SliceIterator<'a>,
}
impl<'self> Iterator<Range> for LineIterator<'self> {
impl<'a> Iterator<Range> for LineIterator<'a> {
fn next(&mut self) -> Option<Range> {
// Loop until we hit whitespace and are in a clump.
loop {
@ -96,7 +96,7 @@ impl<'self> Iterator<Range> for LineIterator<'self> {
}
}
impl<'self> TextRun {
impl<'a> TextRun {
pub fn new(font: &mut Font, text: ~str, decoration: text_decoration::T) -> TextRun {
let glyphs = TextRun::break_and_shape(font, text);
@ -170,12 +170,12 @@ impl<'self> TextRun {
}
pub fn char_len(&self) -> uint {
do self.glyphs.get().iter().fold(0u) |len, slice_glyphs| {
self.glyphs.get().iter().fold(0u, |len, slice_glyphs| {
len + slice_glyphs.get().char_len()
}
})
}
pub fn glyphs(&'self self) -> &'self ~[Arc<GlyphStore>] {
pub fn glyphs(&'a self) -> &'a ~[Arc<GlyphStore>] {
self.glyphs.get()
}
@ -216,7 +216,7 @@ impl<'self> TextRun {
max_piece_width
}
pub fn iter_slices_for_range(&'self self, range: &Range) -> SliceIterator<'self> {
pub fn iter_slices_for_range(&'a self, range: &Range) -> SliceIterator<'a> {
SliceIterator {
glyph_iter: self.glyphs.get().iter(),
range: *range,
@ -224,7 +224,7 @@ impl<'self> TextRun {
}
}
pub fn iter_natural_lines_for_range(&'self self, range: &Range) -> LineIterator<'self> {
pub fn iter_natural_lines_for_range(&'a self, range: &Range) -> LineIterator<'a> {
LineIterator {
range: *range,
clump: None,

View file

@ -24,7 +24,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
let mut out_str: ~str = ~"";
let out_whitespace = match mode {
CompressNone | DiscardNewline => {
for ch in text.iter() {
for ch in text.chars() {
if is_discardable_char(ch, mode) {
// TODO: record skipped char
} else {
@ -40,7 +40,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
CompressWhitespace | CompressWhitespaceNewline => {
let mut in_whitespace: bool = incoming_whitespace;
for ch in text.iter() {
for ch in text.chars() {
// TODO: discard newlines between CJK chars
let mut next_in_whitespace: bool = is_in_whitespace(ch, mode);