diff --git a/src/servo/text/native_font/quartz_native_font.rs b/src/servo/text/native_font/quartz_native_font.rs index 4f5a6ef8758..c4a1e19f541 100644 --- a/src/servo/text/native_font/quartz_native_font.rs +++ b/src/servo/text/native_font/quartz_native_font.rs @@ -5,7 +5,6 @@ export QuartzNativeFont, with_test_native_font, create; import libc::size_t; import ptr::null; import unsafe::reinterpret_cast; -import result::{Result, Ok}; import glyph::GlyphIndex; import cocoa::cg::{ CGDataProviderRef, @@ -18,6 +17,38 @@ import cocoa::cg::cg::{ CGFontRelease }; +mod coretext { + + type CTFontRef = *u8; + type UniChar = libc::c_ushort; + type CGGlyph = libc::c_ushort; + type CFIndex = libc::c_long; + + type CTFontOrientation = u32; + const kCTFontDefaultOrientation: CTFontOrientation = 0; + const kCTFontHorizontalOrientation: CTFontOrientation = 1; + const kCTFontVerticalOrientation: CTFontOrientation = 2; + + type CGFloat = libc::c_double; + + struct CGSize { + width: CGFloat; + height: CGFloat; + } + + type CGAffineTransform = (); + type CTFontDescriptorRef = *u8; + + #[nolink] + #[link_args = "-framework ApplicationServices"] + extern 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; + fn CFRelease(font: CTFontRef); + } +} + struct QuartzNativeFont/& { let fontprov: CGDataProviderRef; let cgfont: CGFontRef; @@ -38,18 +69,57 @@ struct QuartzNativeFont/& { CGDataProviderRelease(self.fontprov); } - fn glyph_index(_codepoint: char) -> Option { - // FIXME - Some(40u) + fn glyph_index(codepoint: char) -> Option { + + import coretext::{UniChar, CGGlyph, CFIndex}; + import coretext::coretext::{CFRelease, CTFontGetGlyphsForCharacters}; + + let ctfont = ctfont_from_cgfont(self.cgfont); + assert ctfont.is_not_null(); + let characters: ~[UniChar] = ~[codepoint as UniChar]; + let glyphs: ~[mut CGGlyph] = ~[mut 0 as CGGlyph]; + let count: CFIndex = 1; + + let result = do vec::as_buf(characters) |character_buf, _l| { + do vec::as_buf(glyphs) |glyph_buf, _l| { + CTFontGetGlyphsForCharacters(ctfont, character_buf, glyph_buf, count) + } + }; + + assert result != false; // FIXME: error handling + + CFRelease(ctfont); + + assert glyphs[0] != 0; // FIXME: error handling + return Some(glyphs[0] as GlyphIndex); } // FIXME: What unit is this returning? Let's have a custom type - fn glyph_h_advance(_glyph: GlyphIndex) -> Option { - // FIXME - Some(15) + fn glyph_h_advance(glyph: GlyphIndex) -> Option { + import coretext::{CGGlyph, kCTFontDefaultOrientation}; + import coretext::coretext::{CFRelease, CTFontGetAdvancesForGlyphs}; + + let ctfont = ctfont_from_cgfont(self.cgfont); + assert ctfont.is_not_null(); + let glyphs = ~[glyph as CGGlyph]; + let advance = do vec::as_buf(glyphs) |glyph_buf, _l| { + CTFontGetAdvancesForGlyphs(ctfont, kCTFontDefaultOrientation, glyph_buf, null(), 1) + }; + + CFRelease(ctfont); + + return Some(advance as int); } } +fn ctfont_from_cgfont(+cgfont: CGFontRef) -> coretext::CTFontRef unsafe { + import coretext::CGFloat; + import coretext::coretext::CTFontCreateWithGraphicsFont; + + assert cgfont.is_not_null(); + CTFontCreateWithGraphicsFont(cgfont, 21f as CGFloat, null(), null()) +} + fn create(buf: &~[u8]) -> Result { let fontprov = vec::as_buf(*buf, |cbuf, len| { CGDataProviderCreateWithData(