diff --git a/src/rust-azure b/src/rust-azure index 3889e647008..8db099ac74d 160000 --- a/src/rust-azure +++ b/src/rust-azure @@ -1 +1 @@ -Subproject commit 3889e647008218eb80d3f94141f542811bf0ffe4 +Subproject commit 8db099ac74ddb4e416eef8f2d237d4ec47787fbe diff --git a/src/rust-freetype b/src/rust-freetype index 47035c52e97..351d5a3398f 160000 --- a/src/rust-freetype +++ b/src/rust-freetype @@ -1 +1 @@ -Subproject commit 47035c52e9737364019012459e8ea7bdc15933e5 +Subproject commit 351d5a3398f088c39d5aec28760d185237a32c66 diff --git a/src/servo-gfx/font.rs b/src/servo-gfx/font.rs index 9a5d77667fb..b996ea490b2 100644 --- a/src/servo-gfx/font.rs +++ b/src/servo-gfx/font.rs @@ -7,6 +7,7 @@ use text::glyph::{GlyphStore, GlyphIndex}; use text::{Shaper, TextRun}; use azure::{AzFloat, AzScaledFontRef}; +use azure::scaled_font::ScaledFont; use azure::azure_hl::{BackendType, ColorPattern}; use core::dvec::DVec; use geom::{Point2D, Rect, Size2D}; @@ -44,13 +45,13 @@ pub trait FontHandleMethods { impl FontHandle { #[cfg(target_os = "macos")] - static pub fn new(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { + static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { quartz::font::QuartzFontHandle::new_from_buffer(fctx, move buf, style) } #[cfg(target_os = "linux")] - static pub fn new(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { - freetype::font::FreeTypeFontHandle::new(fctx, move buf, style) + static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result { + freetype::font::FreeTypeFontHandle::new_from_buffer(fctx, move buf, style) } } @@ -241,23 +242,18 @@ and the renderer can use it to render text. */ pub struct Font { priv handle: FontHandle, - priv mut azure_font: Option, + priv mut azure_font: Option, priv mut shaper: Option<@Shaper>, style: UsedFontStyle, metrics: FontMetrics, backend: BackendType, - - drop { - use azure::bindgen::AzReleaseScaledFont; - do (copy self.azure_font).iter |fontref| { AzReleaseScaledFont(*fontref); } - } } impl Font { static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8], style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font, ()> { - let handle = FontHandle::new(&ctx.handle, move buffer, style); + let handle = FontHandle::new_from_buffer(&ctx.handle, move buffer, style); let handle = if handle.is_ok() { result::unwrap(move handle) } else { @@ -326,25 +322,34 @@ impl Font { return move result; } - priv fn get_azure_font() -> AzScaledFontRef { + // TODO: this should return a borrowed pointer, but I can't figure + // out why borrowck doesn't like my implementation. + + priv fn get_azure_font(&self) -> AzScaledFontRef { // fast path: we've already created the azure font resource match self.azure_font { - Some(azfont) => return azfont, + Some(ref azfont) => return azfont.get_ref(), None => {} } + let mut scaled_font = self.create_azure_font(); + self.azure_font = Some(move scaled_font); + // try again. + return self.get_azure_font(); + } + + #[cfg(target_os="macos")] + priv fn create_azure_font() -> ScaledFont { let ct_font = &self.handle.ctfont; let size = self.style.pt_size as AzFloat; - let scaled_font = azure::scaled_font::ScaledFont::new(self.backend, ct_font, size); + ScaledFont::new(self.backend, ct_font, size) + } - let azure_scaled_font; - unsafe { - azure_scaled_font = scaled_font.azure_scaled_font; - cast::forget(move scaled_font); - } - - self.azure_font = Some(azure_scaled_font); - azure_scaled_font + #[cfg(target_os="linux")] + priv fn create_azure_font() -> ScaledFont { + let cairo_font = self.handle.face; + let size = self.style.pt_size as AzFloat; + ScaledFont::new(self.backend, cairo_font, size) } } @@ -380,7 +385,7 @@ pub impl Font : FontMethods { AzReleaseColorPattern}; let target = rctx.get_draw_target(); - let azfont = self.get_azure_font(); + let azfontref = self.get_azure_font(); let pattern = ColorPattern(color); let azure_pattern = pattern.azure_color_pattern; assert azure_pattern.is_not_null(); @@ -418,7 +423,7 @@ pub impl Font : FontMethods { // TODO(Issue #64): this call needs to move into azure_hl.rs AzDrawTargetFillGlyphs(target.azure_draw_target, - azfont, + azfontref, ptr::to_unsafe_ptr(&glyphbuf), azure_pattern, ptr::to_unsafe_ptr(&options), diff --git a/src/servo-gfx/font_context.rs b/src/servo-gfx/font_context.rs index 71c5de6adb8..ee0e85d1d8c 100644 --- a/src/servo-gfx/font_context.rs +++ b/src/servo-gfx/font_context.rs @@ -137,7 +137,7 @@ pub impl FontContext { }, // TODO(Issue #174): implement by-platform-name font selectors. SelectorPlatformIdentifier(identifier) => { - let result_handle = self.handle.create_font_from_identifier(identifier, copy desc.style); + let result_handle = self.handle.create_font_from_identifier(copy identifier, copy desc.style); result::chain(move result_handle, |handle| { Ok(Font::new_from_adopted_handle(&self, move handle, &desc.style, self.backend)) }) diff --git a/src/servo-gfx/font_list.rs b/src/servo-gfx/font_list.rs index 2aa19998e9a..6193d0b0382 100644 --- a/src/servo-gfx/font_list.rs +++ b/src/servo-gfx/font_list.rs @@ -8,7 +8,7 @@ use send_map::{linear, SendMap}; type FontListHandle/& = quartz::font_list::QuartzFontListHandle; #[cfg(target_os = "linux")] -type FontListHandle/& = freetype::font_list::FreeTypeFontListHandle; +type FontListHandle/& = fontconfig::font_list::FontconfigFontListHandle; pub impl FontListHandle { #[cfg(target_os = "macos")] @@ -18,7 +18,7 @@ pub impl FontListHandle { #[cfg(target_os = "linux")] static pub fn new(fctx: &native::FontContextHandle) -> Result { - Ok(freetype::font_list::FreeTypeFontListHandle::new(fctx)) + Ok(fontconfig::font_list::FontconfigFontListHandle::new(fctx)) } } diff --git a/src/servo-gfx/fontconfig/font_list.rs b/src/servo-gfx/fontconfig/font_list.rs index 109e8b65620..15b0d5f0e81 100644 --- a/src/servo-gfx/fontconfig/font_list.rs +++ b/src/servo-gfx/fontconfig/font_list.rs @@ -1,12 +1,27 @@ -pub struct FontconfigFontContextHandle { - ctx: (), +extern mod freetype; +extern mod fontconfig; - drop { } +use fc = fontconfig; +use ft = freetype; + +use gfx_font::FontHandle; +use gfx_font_list::{FontEntry, FontFamily}; + +use core::dvec::DVec; +use core::send_map::{linear, SendMap}; + +pub struct FontconfigFontListHandle { + fctx: (), } -pub impl FontconfigFontContextHandle { - // this is a placeholder. - static pub fn new() -> FontconfigFontContextHandle { - FontconfigFontContextHandle { ctx: () } +pub impl FontconfigFontListHandle { + static pub fn new(_fctx: &native::FontContextHandle) -> FontconfigFontListHandle { + FontconfigFontListHandle { fctx: () } } -} \ No newline at end of file + + fn get_available_families(&const self, + _fctx: &native::FontContextHandle) + -> linear::LinearMap<~str, @FontFamily> { + fail; + } +} diff --git a/src/servo-gfx/freetype/font.rs b/src/servo-gfx/freetype/font.rs index 9b9968380bd..ea4833a4673 100644 --- a/src/servo-gfx/freetype/font.rs +++ b/src/servo-gfx/freetype/font.rs @@ -1,17 +1,35 @@ extern mod freetype; -use font::{FontMetrics, FractionalPixel}; -use font_context::FreeTypeFontContext; +use font_context::FreeTypeFontContextHandle; +use gfx_font::{ + CSSFontWeight, + FontHandle, + FontHandleMethods, + FontMetrics, + FontTableTag, + FractionalPixel, + SpecifiedFontStyle, + UsedFontStyle, +}; use geometry::Au; use text::glyph::GlyphIndex; use text::util::{float_to_fixed, fixed_to_float}; -use cast::reinterpret_cast; -use ptr::{addr_of, null}; -use vec_as_buf = vec::as_imm_buf; - -use freetype::{ FT_Error, FT_Library, FT_Face, FT_Long, FT_ULong, FT_Size, FT_SizeRec, - FT_UInt, FT_GlyphSlot, FT_Size_Metrics, FT_FaceRec, FT_F26Dot6 }; +use freetype::{ + FTErrorMethods, + FT_Error, + FT_F26Dot6, + FT_Face, + FT_FaceRec, + FT_GlyphSlot, + FT_Library, + FT_Long, + FT_ULong, + FT_Size, + FT_SizeRec, + FT_UInt, + FT_Size_Metrics, +}; use freetype::bindgen::{ FT_Init_FreeType, FT_Done_FreeType, @@ -46,27 +64,70 @@ pub struct FreeTypeFontHandle { } pub impl FreeTypeFontHandle { - static pub fn new(fctx: &FreeTypeFontContext, - buf: ~[u8], pt_size: float) -> Result { - let ft_ctx = fctx.ctx; - assert ft_ctx.is_not_null(); - let face_result: Result = vec_as_buf(buf, |cbuf, _len| { - if FT_New_Memory_Face(ft_ctx, cbuf, (*buf).len() as FT_Long, - 0 as FT_Long, addr_of(&face)).succeeded() { - let res = FT_Set_Char_Size(face, // the face - float_to_fixed_ft(pt_size) as FT_F26Dot6, // char width - float_to_fixed_ft(pt_size) as FT_F26Dot6, // char height - 72, // horiz. DPI - 72); // vert. DPI - if !res.succeeded() { fail ~"unable to set font char size" } - Ok(face) - } else { - Err(()) - } - }); - return do result::chain(face_result) |face| { - Ok(FreeTypeFontHandle { face: face, buf: move buf }) + static pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle, + buf: ~[u8], style: &SpecifiedFontStyle) -> Result { + let ft_ctx: FT_Library = fctx.ctx; + if ft_ctx.is_null() { return Err(()); } + + let face_result = do vec::as_imm_buf(buf) |bytes: *u8, len: uint| { + create_face_from_buffer(ft_ctx, bytes, 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 + // captured binding. + return match face_result { + Ok(face) => Ok(FreeTypeFontHandle { face: face, buf: move buf }), + Err(()) => Err(()) + }; + + fn create_face_from_buffer(lib: FT_Library, + cbuf: *u8, cbuflen: uint, pt_size: float) + -> Result { + + let mut face: FT_Face = ptr::null(); + let face_index = 0 as FT_Long; + let result = FT_New_Memory_Face(lib, cbuf, cbuflen as FT_Long, + face_index, ptr::to_unsafe_ptr(&face)); + + if !result.succeeded() || face.is_null() { + return Err(()); + } + let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6; + let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6; + let h_dpi = 72; + let v_dpi = 72; + + let result = FT_Set_Char_Size(face, char_width, char_height, h_dpi, v_dpi); + if !result.succeeded() { return Err(()); } + + Ok(face) + } + } +} + +pub impl FreeTypeFontHandle : FontHandleMethods { + + // an identifier usable by FontContextHandle to recreate this FontHandle. + pure fn face_identifier() -> ~str { + fail; + } + pure fn family_name() -> ~str { + fail; + } + pure fn face_name() -> ~str { + fail; + } + pure fn is_italic() -> bool { + fail; + } + pure fn boldness() -> CSSFontWeight { + fail; + } + + fn clone_with_style(_fctx: &native::FontContextHandle, + _style: &UsedFontStyle) -> Result { + fail; } pub fn glyph_index(codepoint: char) -> Option { @@ -86,7 +147,7 @@ pub impl FreeTypeFontHandle { if res.succeeded() { unsafe { let void_glyph = (*self.face).glyph; - let slot: FT_GlyphSlot = reinterpret_cast(&void_glyph); + let slot: FT_GlyphSlot = cast::transmute(void_glyph); assert slot.is_not_null(); debug!("metrics: %?", (*slot).metrics); let advance = (*slot).metrics.horiAdvance; @@ -123,6 +184,12 @@ pub impl FreeTypeFontHandle { } } + fn get_table_for_tag(_tag: FontTableTag) -> Option<~[u8]> { + fail; + } +} + +pub impl FreeTypeFontHandle { priv fn get_face_rec() -> &self/FT_FaceRec unsafe { &(*self.face) } @@ -145,11 +212,3 @@ pub impl FreeTypeFontHandle { return geometry::from_frac_px(value * x_scale); } } - -trait FTErrorMethods { - fn succeeded() -> bool; -} - -impl FT_Error : FTErrorMethods { - fn succeeded() -> bool { self == 0 as FT_Error } -} diff --git a/src/servo-gfx/freetype/font_context.rs b/src/servo-gfx/freetype/font_context.rs index 18a168fd77d..75cfad24d82 100644 --- a/src/servo-gfx/freetype/font_context.rs +++ b/src/servo-gfx/freetype/font_context.rs @@ -1,6 +1,7 @@ extern mod freetype; use freetype::{ + FTErrorMethods, FT_Error, FT_Library, }; @@ -9,6 +10,11 @@ use freetype::bindgen::{ FT_Done_FreeType }; +use gfx_font::{ + FontHandle, + UsedFontStyle, +}; +use gfx_font_context::FontContextHandleMethods; pub struct FreeTypeFontContextHandle { ctx: FT_Library, @@ -21,13 +27,21 @@ pub struct FreeTypeFontContextHandle { pub impl FreeTypeFontContextHandle { static pub fn new() -> FreeTypeFontContextHandle { - let lib: FT_Library = ptr::null(); - let res = FT_Init_FreeType(ptr::addr_of(&lib)); - // FIXME: error handling - assert res == 0 as FT_Error; + let ctx: FT_Library = ptr::null(); + let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx)); + if !result.succeeded() { fail; } - FreeTypeFontContext { - ctx: lib, + FreeTypeFontContextHandle { + ctx: ctx, } } -} \ No newline at end of file +} + +pub impl FreeTypeFontContextHandle : FontContextHandleMethods { + fn create_font_from_identifier(_identifier: ~str, _style: UsedFontStyle) + -> Result { + + fail; + } +} +