mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Upgrade to latest Rust.
This commit is contained in:
parent
728fb9a7de
commit
a7ef1cd35e
127 changed files with 1892 additions and 2501 deletions
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))))
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(());
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(());
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue