diff --git a/src/servo/text/font.rs b/src/servo/text/font.rs index e570c2f509e..2c514b02295 100644 --- a/src/servo/text/font.rs +++ b/src/servo/text/font.rs @@ -1,4 +1,4 @@ -export Font, test_font_bin, create_test_font; +export Font, FontMetrics, test_font_bin, create_test_font; use glyph::GlyphIndex; use vec_to_ptr = vec::raw::to_ptr; @@ -16,6 +16,7 @@ struct Font { lib: @FontLibrary, fontbuf: @~[u8], native_font: NativeFont, + metrics: FontMetrics } impl Font { @@ -35,14 +36,27 @@ impl Font { } } -fn Font(lib: @FontLibrary, fontbuf: @~[u8], +native_font: NativeFont) -> Font { +fn Font(lib: @FontLibrary, fontbuf: @~[u8], +native_font: NativeFont, +metrics: FontMetrics) -> Font { Font { lib: lib, fontbuf : fontbuf, native_font : move native_font, + metrics: move metrics } } +struct FontMetrics { + underline_size: float, + underline_offset: float, + leading: float, + x_height: float, + + em_height: float, + em_ascent: float, + em_descent: float, + max_advance: float +} + const TEST_FONT: [u8 * 33004] = #include_bin("JosefinSans-SemiBold.ttf"); fn test_font_bin() -> ~[u8] { diff --git a/src/servo/text/font_library.rs b/src/servo/text/font_library.rs index 0073d657af2..584dcd3743a 100644 --- a/src/servo/text/font_library.rs +++ b/src/servo/text/font_library.rs @@ -46,7 +46,8 @@ fn create_font(lib: @FontLibrary, native_lib: &native::NativeFontLibrary) -> Res } else { return Err(native_font.get_err()); }; - return Ok(@Font(lib, font_bin, native_font)); + let metrics = native_font.get_metrics(); + return Ok(@Font(lib, font_bin, native_font, metrics)); } #[cfg(target_os = "linux")] diff --git a/src/servo/text/native_font/ft_native_font.rs b/src/servo/text/native_font/ft_native_font.rs index 2f93eb7f552..a78bc8d89b5 100644 --- a/src/servo/text/native_font/ft_native_font.rs +++ b/src/servo/text/native_font/ft_native_font.rs @@ -4,6 +4,7 @@ use vec_as_buf = vec::as_imm_buf; use ptr::{addr_of, null}; use unsafe::reinterpret_cast; use glyph::GlyphIndex; +use font::FontMetrics; use azure::freetype; use freetype::{ FT_Error, FT_Library, FT_Face, FT_Long, FT_ULong, FT_UInt, FT_GlyphSlot }; use freetype::bindgen::{ @@ -67,6 +68,20 @@ impl FreeTypeNativeFont { return None; } } + + fn get_metrics() -> FontMetrics { + /* TODO: complete me (Issue #76) */ + return FontMetrics { + underline_size: 0.0, + underline_offset: 0.0, + leading: 0.0, + x_height: 0.0, + em_ascent: 0.0, + em_descent: 0.0, + em_height: 0.0, + max_advance: 0.0 + } + } } fn create(lib: &FT_Library, buf: @~[u8]) -> Result { diff --git a/src/servo/text/native_font/quartz_native_font.rs b/src/servo/text/native_font/quartz_native_font.rs index bbf1ca62dc6..237b2bc7325 100644 --- a/src/servo/text/native_font/quartz_native_font.rs +++ b/src/servo/text/native_font/quartz_native_font.rs @@ -2,6 +2,8 @@ extern mod cocoa; export QuartzNativeFont, with_test_native_font, create; +use font::FontMetrics; + use libc::size_t; use ptr::null; use glyph::GlyphIndex; @@ -38,6 +40,16 @@ mod coretext { height: CGFloat, } + struct CGPoint { + x: CGFloat, + y: CGFloat, + } + + struct CGRect { + origin: CGPoint, + size: CGSize + } + type CGAffineTransform = (); type CTFontDescriptorRef = *u8; @@ -47,6 +59,17 @@ mod coretext { fn CTFontCreateWithGraphicsFont(graphicsFont: CGFontRef, size: CGFloat, matrix: *CGAffineTransform, attributes: CTFontDescriptorRef) -> CTFontRef; fn CTFontGetGlyphsForCharacters(font: CTFontRef, characters: *UniChar, glyphs: *CGGlyph, count: CFIndex) -> bool; fn CTFontGetAdvancesForGlyphs(font: CTFontRef, orientation: CTFontOrientation, glyphs: *CGGlyph, advances: *CGSize, count: CFIndex) -> libc::c_double; + + /* metrics API */ + fn CTFontGetAscent(font: CTFontRef) -> libc::c_float; + fn CTFontGetDescent(font: CTFontRef) -> libc::c_float; + fn CTFontGetLeading(font: CTFontRef) -> libc::c_float; + fn CTFontGetUnitsPerEm(font: CTFontRef) -> libc::c_uint; + fn CTFontGetUnderlinePosition(font: CTFontRef) -> libc::c_float; + fn CTFontGetUnderlineThickness(font: CTFontRef) -> libc::c_float; + fn CTFontGetXHeight(font: CTFontRef) -> libc::c_float; + fn CTFontGetBoundingBox(font: CTFontRef) -> CGRect; + fn CFRelease(font: CTFontRef); } } @@ -120,6 +143,30 @@ impl QuartzNativeFont { return Some(advance as int); } + + fn get_metrics() -> FontMetrics { + use coretext::CGRect; + use coretext::coretext::*; + + let ctfont = self.ctfont; + assert ctfont.is_not_null(); + + let convFactor : float = 1.0 / (CTFontGetUnitsPerEm(ctfont) as float); + let bounding_rect: CGRect = CTFontGetBoundingBox(ctfont); + let em_ascent = CTFontGetAscent(ctfont) as float * convFactor; + let em_descent = CTFontGetDescent(ctfont) as float * convFactor; + + return FontMetrics { + underline_size: CTFontGetUnderlineThickness(ctfont) as float * convFactor, + underline_offset: CTFontGetUnderlinePosition(ctfont) as float * convFactor, + leading: CTFontGetLeading(ctfont) as float * convFactor, + x_height: CTFontGetXHeight(ctfont) as float * convFactor, + em_ascent: CTFontGetAscent(ctfont) as float * convFactor, + em_descent: CTFontGetDescent(ctfont) as float * convFactor, + em_height: em_ascent + em_descent, + max_advance: bounding_rect.size.width as float * convFactor, + } + } } fn ctfont_from_cgfont(cgfont: CGFontRef) -> coretext::CTFontRef {