mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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:
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
|
|
@ -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),
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue