mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +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 text::{Shaper, TextRun};
|
||||||
|
|
||||||
use azure::{AzFloat, AzScaledFontRef};
|
use azure::{AzFloat, AzScaledFontRef};
|
||||||
|
use azure::scaled_font::ScaledFont;
|
||||||
use azure::azure_hl::{BackendType, ColorPattern};
|
use azure::azure_hl::{BackendType, ColorPattern};
|
||||||
use core::dvec::DVec;
|
use core::dvec::DVec;
|
||||||
use geom::{Point2D, Rect, Size2D};
|
use geom::{Point2D, Rect, Size2D};
|
||||||
|
@ -44,13 +45,13 @@ pub trait FontHandleMethods {
|
||||||
|
|
||||||
impl FontHandle {
|
impl FontHandle {
|
||||||
#[cfg(target_os = "macos")]
|
#[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)
|
quartz::font::QuartzFontHandle::new_from_buffer(fctx, move buf, style)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
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, ()> {
|
||||||
freetype::font::FreeTypeFontHandle::new(fctx, move buf, style)
|
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 {
|
pub struct Font {
|
||||||
priv handle: FontHandle,
|
priv handle: FontHandle,
|
||||||
priv mut azure_font: Option<AzScaledFontRef>,
|
priv mut azure_font: Option<ScaledFont>,
|
||||||
priv mut shaper: Option<@Shaper>,
|
priv mut shaper: Option<@Shaper>,
|
||||||
style: UsedFontStyle,
|
style: UsedFontStyle,
|
||||||
metrics: FontMetrics,
|
metrics: FontMetrics,
|
||||||
backend: BackendType,
|
backend: BackendType,
|
||||||
|
|
||||||
drop {
|
|
||||||
use azure::bindgen::AzReleaseScaledFont;
|
|
||||||
do (copy self.azure_font).iter |fontref| { AzReleaseScaledFont(*fontref); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Font {
|
impl Font {
|
||||||
static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8],
|
static fn new_from_buffer(ctx: &FontContext, buffer: ~[u8],
|
||||||
style: &SpecifiedFontStyle, backend: BackendType) -> Result<@Font, ()> {
|
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() {
|
let handle = if handle.is_ok() {
|
||||||
result::unwrap(move handle)
|
result::unwrap(move handle)
|
||||||
} else {
|
} else {
|
||||||
|
@ -326,25 +322,34 @@ impl Font {
|
||||||
return move result;
|
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
|
// fast path: we've already created the azure font resource
|
||||||
match self.azure_font {
|
match self.azure_font {
|
||||||
Some(azfont) => return azfont,
|
Some(ref azfont) => return azfont.get_ref(),
|
||||||
None => {}
|
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 ct_font = &self.handle.ctfont;
|
||||||
let size = self.style.pt_size as AzFloat;
|
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;
|
#[cfg(target_os="linux")]
|
||||||
unsafe {
|
priv fn create_azure_font() -> ScaledFont {
|
||||||
azure_scaled_font = scaled_font.azure_scaled_font;
|
let cairo_font = self.handle.face;
|
||||||
cast::forget(move scaled_font);
|
let size = self.style.pt_size as AzFloat;
|
||||||
}
|
ScaledFont::new(self.backend, cairo_font, size)
|
||||||
|
|
||||||
self.azure_font = Some(azure_scaled_font);
|
|
||||||
azure_scaled_font
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +385,7 @@ pub impl Font : FontMethods {
|
||||||
AzReleaseColorPattern};
|
AzReleaseColorPattern};
|
||||||
|
|
||||||
let target = rctx.get_draw_target();
|
let target = rctx.get_draw_target();
|
||||||
let azfont = self.get_azure_font();
|
let azfontref = self.get_azure_font();
|
||||||
let pattern = ColorPattern(color);
|
let pattern = ColorPattern(color);
|
||||||
let azure_pattern = pattern.azure_color_pattern;
|
let azure_pattern = pattern.azure_color_pattern;
|
||||||
assert azure_pattern.is_not_null();
|
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
|
// TODO(Issue #64): this call needs to move into azure_hl.rs
|
||||||
AzDrawTargetFillGlyphs(target.azure_draw_target,
|
AzDrawTargetFillGlyphs(target.azure_draw_target,
|
||||||
azfont,
|
azfontref,
|
||||||
ptr::to_unsafe_ptr(&glyphbuf),
|
ptr::to_unsafe_ptr(&glyphbuf),
|
||||||
azure_pattern,
|
azure_pattern,
|
||||||
ptr::to_unsafe_ptr(&options),
|
ptr::to_unsafe_ptr(&options),
|
||||||
|
|
|
@ -137,7 +137,7 @@ pub impl FontContext {
|
||||||
},
|
},
|
||||||
// TODO(Issue #174): implement by-platform-name font selectors.
|
// TODO(Issue #174): implement by-platform-name font selectors.
|
||||||
SelectorPlatformIdentifier(identifier) => {
|
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| {
|
result::chain(move result_handle, |handle| {
|
||||||
Ok(Font::new_from_adopted_handle(&self, move handle, &desc.style, self.backend))
|
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;
|
type FontListHandle/& = quartz::font_list::QuartzFontListHandle;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
type FontListHandle/& = freetype::font_list::FreeTypeFontListHandle;
|
type FontListHandle/& = fontconfig::font_list::FontconfigFontListHandle;
|
||||||
|
|
||||||
pub impl FontListHandle {
|
pub impl FontListHandle {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -18,7 +18,7 @@ pub impl FontListHandle {
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
static pub fn new(fctx: &native::FontContextHandle) -> Result<FontListHandle, ()> {
|
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 {
|
extern mod freetype;
|
||||||
ctx: (),
|
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 {
|
pub impl FontconfigFontListHandle {
|
||||||
// this is a placeholder.
|
static pub fn new(_fctx: &native::FontContextHandle) -> FontconfigFontListHandle {
|
||||||
static pub fn new() -> FontconfigFontContextHandle {
|
FontconfigFontListHandle { fctx: () }
|
||||||
FontconfigFontContextHandle { ctx: () }
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
fn get_available_families(&const self,
|
||||||
|
_fctx: &native::FontContextHandle)
|
||||||
|
-> linear::LinearMap<~str, @FontFamily> {
|
||||||
|
fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,35 @@
|
||||||
extern mod freetype;
|
extern mod freetype;
|
||||||
|
|
||||||
use font::{FontMetrics, FractionalPixel};
|
use font_context::FreeTypeFontContextHandle;
|
||||||
use font_context::FreeTypeFontContext;
|
use gfx_font::{
|
||||||
|
CSSFontWeight,
|
||||||
|
FontHandle,
|
||||||
|
FontHandleMethods,
|
||||||
|
FontMetrics,
|
||||||
|
FontTableTag,
|
||||||
|
FractionalPixel,
|
||||||
|
SpecifiedFontStyle,
|
||||||
|
UsedFontStyle,
|
||||||
|
};
|
||||||
use geometry::Au;
|
use geometry::Au;
|
||||||
use text::glyph::GlyphIndex;
|
use text::glyph::GlyphIndex;
|
||||||
use text::util::{float_to_fixed, fixed_to_float};
|
use text::util::{float_to_fixed, fixed_to_float};
|
||||||
|
|
||||||
use cast::reinterpret_cast;
|
use freetype::{
|
||||||
use ptr::{addr_of, null};
|
FTErrorMethods,
|
||||||
use vec_as_buf = vec::as_imm_buf;
|
FT_Error,
|
||||||
|
FT_F26Dot6,
|
||||||
use freetype::{ FT_Error, FT_Library, FT_Face, FT_Long, FT_ULong, FT_Size, FT_SizeRec,
|
FT_Face,
|
||||||
FT_UInt, FT_GlyphSlot, FT_Size_Metrics, FT_FaceRec, FT_F26Dot6 };
|
FT_FaceRec,
|
||||||
|
FT_GlyphSlot,
|
||||||
|
FT_Library,
|
||||||
|
FT_Long,
|
||||||
|
FT_ULong,
|
||||||
|
FT_Size,
|
||||||
|
FT_SizeRec,
|
||||||
|
FT_UInt,
|
||||||
|
FT_Size_Metrics,
|
||||||
|
};
|
||||||
use freetype::bindgen::{
|
use freetype::bindgen::{
|
||||||
FT_Init_FreeType,
|
FT_Init_FreeType,
|
||||||
FT_Done_FreeType,
|
FT_Done_FreeType,
|
||||||
|
@ -46,27 +64,70 @@ pub struct FreeTypeFontHandle {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl FreeTypeFontHandle {
|
pub impl FreeTypeFontHandle {
|
||||||
static pub fn new(fctx: &FreeTypeFontContext,
|
static pub fn new_from_buffer(fctx: &FreeTypeFontContextHandle,
|
||||||
buf: ~[u8], pt_size: float) -> Result<FreeTypeFontHandle, ()> {
|
buf: ~[u8], style: &SpecifiedFontStyle) -> Result<FreeTypeFontHandle, ()> {
|
||||||
let ft_ctx = fctx.ctx;
|
let ft_ctx: FT_Library = fctx.ctx;
|
||||||
assert ft_ctx.is_not_null();
|
if ft_ctx.is_null() { return Err(()); }
|
||||||
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,
|
let face_result = do vec::as_imm_buf(buf) |bytes: *u8, len: uint| {
|
||||||
0 as FT_Long, addr_of(&face)).succeeded() {
|
create_face_from_buffer(ft_ctx, bytes, len, style.pt_size)
|
||||||
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 })
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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> {
|
pub fn glyph_index(codepoint: char) -> Option<GlyphIndex> {
|
||||||
|
@ -86,7 +147,7 @@ pub impl FreeTypeFontHandle {
|
||||||
if res.succeeded() {
|
if res.succeeded() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let void_glyph = (*self.face).glyph;
|
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();
|
assert slot.is_not_null();
|
||||||
debug!("metrics: %?", (*slot).metrics);
|
debug!("metrics: %?", (*slot).metrics);
|
||||||
let advance = (*slot).metrics.horiAdvance;
|
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 {
|
priv fn get_face_rec() -> &self/FT_FaceRec unsafe {
|
||||||
&(*self.face)
|
&(*self.face)
|
||||||
}
|
}
|
||||||
|
@ -145,11 +212,3 @@ pub impl FreeTypeFontHandle {
|
||||||
return geometry::from_frac_px(value * x_scale);
|
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;
|
extern mod freetype;
|
||||||
|
|
||||||
use freetype::{
|
use freetype::{
|
||||||
|
FTErrorMethods,
|
||||||
FT_Error,
|
FT_Error,
|
||||||
FT_Library,
|
FT_Library,
|
||||||
};
|
};
|
||||||
|
@ -9,6 +10,11 @@ use freetype::bindgen::{
|
||||||
FT_Done_FreeType
|
FT_Done_FreeType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use gfx_font::{
|
||||||
|
FontHandle,
|
||||||
|
UsedFontStyle,
|
||||||
|
};
|
||||||
|
use gfx_font_context::FontContextHandleMethods;
|
||||||
|
|
||||||
pub struct FreeTypeFontContextHandle {
|
pub struct FreeTypeFontContextHandle {
|
||||||
ctx: FT_Library,
|
ctx: FT_Library,
|
||||||
|
@ -21,13 +27,21 @@ pub struct FreeTypeFontContextHandle {
|
||||||
|
|
||||||
pub impl FreeTypeFontContextHandle {
|
pub impl FreeTypeFontContextHandle {
|
||||||
static pub fn new() -> FreeTypeFontContextHandle {
|
static pub fn new() -> FreeTypeFontContextHandle {
|
||||||
let lib: FT_Library = ptr::null();
|
let ctx: FT_Library = ptr::null();
|
||||||
let res = FT_Init_FreeType(ptr::addr_of(&lib));
|
let result = FT_Init_FreeType(ptr::to_unsafe_ptr(&ctx));
|
||||||
// FIXME: error handling
|
if !result.succeeded() { fail; }
|
||||||
assert res == 0 as FT_Error;
|
|
||||||
|
|
||||||
FreeTypeFontContext {
|
FreeTypeFontContextHandle {
|
||||||
ctx: lib,
|
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