Skip to content

Commit

Permalink
Fix the linux build by stubbing out FreeType handles that haven't bee…
Browse files Browse the repository at this point in the history
…n implemented yet. Add some glue to create ScaledFonts for Cairo backend on linux. Closes #207.
  • Loading branch information
Brian J. Burg committed Nov 14, 2012
1 parent 8d5759d commit 77a5d8b
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 80 deletions.
2 changes: 1 addition & 1 deletion src/rust-azure
Submodule rust-azure updated from 3889e6 to 8db099
2 changes: 1 addition & 1 deletion src/rust-freetype
Submodule rust-freetype updated from 47035c to 351d5a
51 changes: 28 additions & 23 deletions src/servo-gfx/font.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);

let azure_scaled_font;
unsafe {
azure_scaled_font = scaled_font.azure_scaled_font;
cast::forget(move scaled_font);
}
ScaledFont::new(self.backend, ct_font, size)
}

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

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion src/servo-gfx/font_context.rs
Expand Up @@ -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))
})
Expand Down
4 changes: 2 additions & 2 deletions src/servo-gfx/font_list.rs
Expand Up @@ -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")]
Expand All @@ -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))
}
}

Expand Down
31 changes: 23 additions & 8 deletions src/servo-gfx/fontconfig/font_list.rs
@@ -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;
}
}
133 changes: 96 additions & 37 deletions src/servo-gfx/freetype/font.rs
@@ -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,
Expand Down Expand Up @@ -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> {
Expand All @@ -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;
Expand Down Expand Up @@ -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)
}
Expand All @@ -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 }
}

0 comments on commit 77a5d8b

Please sign in to comment.