mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Implement FreeTypeNativeFont.glyph_h_advance
This commit is contained in:
parent
2967527abb
commit
c92c1c661f
3 changed files with 85 additions and 12 deletions
|
@ -15,12 +15,18 @@ type NativeFont/& = quartz_native_font::QuartzNativeFont;
|
|||
#[cfg(target_os = "linux")]
|
||||
type NativeFont/& = ft_native_font::FreeTypeNativeFont;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn with_test_native_font(f: fn@(NativeFont)) {
|
||||
fail
|
||||
quartz_native_font::with_test_native_font(f);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn with_test_native_font(f: fn@(nf: &NativeFont)) {
|
||||
ft_native_font::with_test_native_font(f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[ignore(cfg(target_os = "macos"))]
|
||||
fn should_get_glyph_indexes() {
|
||||
with_test_native_font { |font|
|
||||
let idx = font.glyph_index('w');
|
||||
|
@ -29,10 +35,28 @@ fn should_get_glyph_indexes() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
#[ignore(cfg(target_os = "macos"))]
|
||||
fn should_return_none_glyph_index_for_bad_codepoints() {
|
||||
with_test_native_font { |font|
|
||||
let idx = font.glyph_index(0 as char);
|
||||
assert idx == none;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(target_os = "macos"))]
|
||||
fn should_get_glyph_h_advance() {
|
||||
with_test_native_font { |font|
|
||||
let adv = font.glyph_h_advance(40u);
|
||||
assert adv == 15;
|
||||
assert adv == some(15);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore(cfg(target_os = "macos"))]
|
||||
fn should_return_none_glyph_h_advance_for_bad_codepoints() {
|
||||
with_test_native_font { |font|
|
||||
let adv = font.glyph_h_advance(-1 as uint);
|
||||
assert adv == none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
export FreeTypeNativeFont;
|
||||
export FreeTypeNativeFont, with_test_native_font;
|
||||
|
||||
import vec_as_buf = vec::as_buf;
|
||||
import result::{result, ok, err};
|
||||
import ptr::{addr_of, null};
|
||||
import unsafe::reinterpret_cast;
|
||||
import glyph::GlyphIndex;
|
||||
import azure::freetype;
|
||||
import freetype::{ FT_Error, FT_Library, FT_Face, FT_Long };
|
||||
import freetype::{ FT_Error, FT_Library, FT_Face, FT_Long, FT_ULong, FT_UInt, FT_GlyphSlot };
|
||||
import freetype::bindgen::{
|
||||
FT_Init_FreeType,
|
||||
FT_Done_FreeType,
|
||||
FT_New_Memory_Face,
|
||||
FT_Done_Face
|
||||
FT_Done_Face,
|
||||
FT_Get_Char_Index,
|
||||
FT_Load_Glyph,
|
||||
FT_Set_Char_Size
|
||||
};
|
||||
|
||||
class FreeTypeNativeFont/& {
|
||||
|
@ -28,13 +32,36 @@ class FreeTypeNativeFont/& {
|
|||
}
|
||||
}
|
||||
|
||||
fn glyph_index(_codepoint: char) -> option<GlyphIndex> {
|
||||
fail;
|
||||
fn glyph_index(codepoint: char) -> option<GlyphIndex> {
|
||||
assert self.face.is_not_null();
|
||||
let idx = FT_Get_Char_Index(self.face, codepoint as FT_ULong);
|
||||
ret if idx != 0 as FT_UInt {
|
||||
some(idx as GlyphIndex)
|
||||
} else {
|
||||
#warn("Invalid codepoint: %?", codepoint);
|
||||
none
|
||||
};
|
||||
}
|
||||
|
||||
// FIXME: What unit is this returning? Let's have a custom type
|
||||
fn glyph_h_advance(_glyph: GlyphIndex) -> int {
|
||||
fail;
|
||||
fn glyph_h_advance(glyph: GlyphIndex) -> option<int> {
|
||||
assert self.face.is_not_null();
|
||||
let res = FT_Load_Glyph(self.face, glyph as FT_UInt, 0);
|
||||
if res.succeeded() {
|
||||
unsafe {
|
||||
let void_glyph = (*self.face).glyph;
|
||||
let slot: FT_GlyphSlot = reinterpret_cast(void_glyph);
|
||||
assert slot.is_not_null();
|
||||
let advance = (*slot).metrics.horiAdvance;
|
||||
#debug("h_advance for %? is %?", glyph, advance);
|
||||
// FIXME: Dividing by 64 converts to pixels, which
|
||||
// is not the unit we should be using
|
||||
ret some((advance / 64) as int);
|
||||
}
|
||||
} else {
|
||||
#warn("Unable to load glyph %?. reason: %?", glyph, res);
|
||||
ret none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +71,9 @@ fn create(lib: FT_Library, buf: &[u8]) -> result<FreeTypeNativeFont, ()> {
|
|||
ret vec_as_buf(*buf) {|cbuf|
|
||||
if FT_New_Memory_Face(lib, cbuf, (*buf).len() as FT_Long,
|
||||
0 as FT_Long, addr_of(face)).succeeded() {
|
||||
// FIXME: These values are placeholders
|
||||
let res = FT_Set_Char_Size(face, 0, 20*64, 0, 72);
|
||||
if !res.succeeded() { fail "unable to set font char size" }
|
||||
ok(FreeTypeNativeFont(face))
|
||||
} else {
|
||||
err(())
|
||||
|
@ -55,6 +85,18 @@ impl methods for FT_Error {
|
|||
fn succeeded() -> bool { self == 0 as FT_Error }
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn with_test_native_font(f: fn@(nf: &NativeFont)) {
|
||||
import font::test_font_bin;
|
||||
import unwrap_result = result::unwrap;
|
||||
|
||||
with_lib { |lib|
|
||||
let buf = test_font_bin();
|
||||
let font = unwrap_result(create(lib, &buf));
|
||||
f(&font);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn with_lib(f: fn@(FT_Library)) {
|
||||
let lib: FT_Library = null();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export QuartzNativeFont, with_test_native_font;
|
||||
|
||||
import glyph::GlyphIndex;
|
||||
|
||||
class QuartzNativeFont/& {
|
||||
|
@ -10,7 +12,12 @@ class QuartzNativeFont/& {
|
|||
}
|
||||
|
||||
// FIXME: What unit is this returning? Let's have a custom type
|
||||
fn glyph_h_advance(_glyph: GlyphIndex) -> int {
|
||||
fn glyph_h_advance(_glyph: GlyphIndex) -> option<int> {
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn with_test_native_font(f: fn@(nf: &NativeFont)) {
|
||||
fail
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue