mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +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")]
|
#[cfg(target_os = "linux")]
|
||||||
type NativeFont/& = ft_native_font::FreeTypeNativeFont;
|
type NativeFont/& = ft_native_font::FreeTypeNativeFont;
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
fn with_test_native_font(f: fn@(NativeFont)) {
|
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]
|
#[test]
|
||||||
#[ignore]
|
#[ignore(cfg(target_os = "macos"))]
|
||||||
fn should_get_glyph_indexes() {
|
fn should_get_glyph_indexes() {
|
||||||
with_test_native_font { |font|
|
with_test_native_font { |font|
|
||||||
let idx = font.glyph_index('w');
|
let idx = font.glyph_index('w');
|
||||||
|
@ -29,10 +35,28 @@ fn should_get_glyph_indexes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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() {
|
fn should_get_glyph_h_advance() {
|
||||||
with_test_native_font { |font|
|
with_test_native_font { |font|
|
||||||
let adv = font.glyph_h_advance(40u);
|
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 vec_as_buf = vec::as_buf;
|
||||||
import result::{result, ok, err};
|
import result::{result, ok, err};
|
||||||
import ptr::{addr_of, null};
|
import ptr::{addr_of, null};
|
||||||
|
import unsafe::reinterpret_cast;
|
||||||
import glyph::GlyphIndex;
|
import glyph::GlyphIndex;
|
||||||
import azure::freetype;
|
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::{
|
import freetype::bindgen::{
|
||||||
FT_Init_FreeType,
|
FT_Init_FreeType,
|
||||||
FT_Done_FreeType,
|
FT_Done_FreeType,
|
||||||
FT_New_Memory_Face,
|
FT_New_Memory_Face,
|
||||||
FT_Done_Face
|
FT_Done_Face,
|
||||||
|
FT_Get_Char_Index,
|
||||||
|
FT_Load_Glyph,
|
||||||
|
FT_Set_Char_Size
|
||||||
};
|
};
|
||||||
|
|
||||||
class FreeTypeNativeFont/& {
|
class FreeTypeNativeFont/& {
|
||||||
|
@ -28,13 +32,36 @@ class FreeTypeNativeFont/& {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glyph_index(_codepoint: char) -> option<GlyphIndex> {
|
fn glyph_index(codepoint: char) -> option<GlyphIndex> {
|
||||||
fail;
|
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
|
// 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;
|
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|
|
ret vec_as_buf(*buf) {|cbuf|
|
||||||
if FT_New_Memory_Face(lib, cbuf, (*buf).len() as FT_Long,
|
if FT_New_Memory_Face(lib, cbuf, (*buf).len() as FT_Long,
|
||||||
0 as FT_Long, addr_of(face)).succeeded() {
|
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))
|
ok(FreeTypeNativeFont(face))
|
||||||
} else {
|
} else {
|
||||||
err(())
|
err(())
|
||||||
|
@ -55,6 +85,18 @@ impl methods for FT_Error {
|
||||||
fn succeeded() -> bool { self == 0 as 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)]
|
#[cfg(test)]
|
||||||
fn with_lib(f: fn@(FT_Library)) {
|
fn with_lib(f: fn@(FT_Library)) {
|
||||||
let lib: FT_Library = null();
|
let lib: FT_Library = null();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
export QuartzNativeFont, with_test_native_font;
|
||||||
|
|
||||||
import glyph::GlyphIndex;
|
import glyph::GlyphIndex;
|
||||||
|
|
||||||
class QuartzNativeFont/& {
|
class QuartzNativeFont/& {
|
||||||
|
@ -10,7 +12,12 @@ class QuartzNativeFont/& {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: What unit is this returning? Let's have a custom type
|
// 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;
|
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