Fix the linux build by stubbing out FreeType handles that haven't been implemented yet. Add some glue to create ScaledFonts for Cairo backend on linux. Closes #207.

This commit is contained in:
Brian J. Burg 2012-11-13 18:29:07 -08:00
parent 8d5759d8a6
commit 77a5d8b107
8 changed files with 173 additions and 80 deletions

@ -1 +1 @@
Subproject commit 3889e647008218eb80d3f94141f542811bf0ffe4
Subproject commit 8db099ac74ddb4e416eef8f2d237d4ec47787fbe

@ -1 +1 @@
Subproject commit 47035c52e9737364019012459e8ea7bdc15933e5
Subproject commit 351d5a3398f088c39d5aec28760d185237a32c66

View file

@ -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<FontHandle, ()> {
static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
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<FontHandle, ()> {
freetype::font::FreeTypeFontHandle::new(fctx, move buf, style)
static pub fn new_from_buffer(fctx: &native::FontContextHandle, buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
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<AzScaledFontRef>,
priv mut azure_font: Option<ScaledFont>,
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),

View file

@ -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))
})

View file

@ -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<FontListHandle, ()> {
Ok(freetype::font_list::FreeTypeFontListHandle::new(fctx))
Ok(fontconfig::font_list::FontconfigFontListHandle::new(fctx))
}
}

View file

@ -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: () }
}
}
fn get_available_families(&const self,
_fctx: &native::FontContextHandle)
-> linear::LinearMap<~str, @FontFamily> {
fail;
}
}

View file

@ -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<FreeTypeFontHandle, ()> {
let ft_ctx = fctx.ctx;
assert ft_ctx.is_not_null();
let face_result: Result<FT_Face,()> = 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<FreeTypeFontHandle, ()> {
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<FT_Face, ()> {
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<FontHandle, ()> {
fail;
}
pub fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
@ -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 }
}

View file

@ -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,
}
}
}
}
pub impl FreeTypeFontContextHandle : FontContextHandleMethods {
fn create_font_from_identifier(_identifier: ~str, _style: UsedFontStyle)
-> Result<FontHandle, ()> {
fail;
}
}