From 4e63f18f0f7736d9af2dc5b646630983ff609113 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Thu, 26 Jun 2014 15:59:42 +1000 Subject: [PATCH] Add support for creating freetype faces (for linux/android) from a memory buffer. --- azure-c.cpp | 17 ++++++++++++++++- azure-c.h | 3 ++- azure.rc | 2 +- azure.rs | 4 +++- include/mozilla/gfx/2D.h | 2 ++ scaled_font.rs | 24 +++++++++++++++++++----- src/gfx/2d/ScaledFontFreetype.cpp | 13 ++++++++++--- 7 files changed, 53 insertions(+), 12 deletions(-) diff --git a/azure-c.cpp b/azure-c.cpp index ccf1662..93398d7 100644 --- a/azure-c.cpp +++ b/azure-c.cpp @@ -459,11 +459,26 @@ AzDrawTargetSetTransform(AzDrawTargetRef aDrawTarget, } extern "C" AzFontOptions* -AzCreateFontOptions(char *aName, AzFontStyle aStyle) { +AzCreateFontOptionsForName(char *aName, AzFontStyle aStyle) { #ifdef MOZ_ENABLE_FREETYPE gfx::FontOptions *options = new gfx::FontOptions; options->mName = std::string(aName); options->mStyle = static_cast(aStyle); + options->mData = NULL; + options->mDataSize = 0; + return options; + #else + abort(); + #endif +} + +extern "C" AzFontOptions* +AzCreateFontOptionsForData(uint8_t *aFontData, uint32_t aFontDataSize) { + #ifdef MOZ_ENABLE_FREETYPE + gfx::FontOptions *options = new gfx::FontOptions; + options->mStyle = gfx::FONT_STYLE_NORMAL; + options->mData = aFontData; + options->mDataSize = aFontDataSize; return options; #else abort(); diff --git a/azure-c.h b/azure-c.h index a4f06b6..2393adb 100644 --- a/azure-c.h +++ b/azure-c.h @@ -380,7 +380,8 @@ void AzReleaseScaledFont(AzScaledFontRef aFont); /* Helpers */ typedef void AzFontOptions; -AzFontOptions* AzCreateFontOptions(char *aName, AzFontStyle aStyle); +AzFontOptions* AzCreateFontOptionsForName(char *aName, AzFontStyle aStyle); +AzFontOptions* AzCreateFontOptionsForData(uint8_t *aFontData, uint32_t aFontDataSize); void AzDestroyFontOptions(AzFontOptions* aOptions); AzGLContext AzSkiaGetCurrentGLContext(); diff --git a/azure.rc b/azure.rc index 910ae3e..a5ac942 100644 --- a/azure.rc +++ b/azure.rc @@ -73,7 +73,7 @@ pub use azure::{AzFontOptions, AzFloat, enum_AzSurfaceType, AZ_SURFACE_DATA, AzDrawTargetDrawSurface, AzDrawTargetGetSnapshot, AzDrawTargetCreateSourceSurfaceFromData, AzReleaseSourceSurface, AzSourceSurfaceGetSize, AzSourceSurfaceGetFormat, AzSourceSurfaceGetDataSurface, AzDataSourceSurfaceGetData, AzDataSourceSurfaceGetStride, AzCreateScaledFontForNativeFont, AzReleaseScaledFont, AzDrawTargetSetTransform, - AzCreateFontOptions, AzDestroyFontOptions, AzSkiaGetCurrentGLContext, AzCreatePathBuilder, + AzCreateFontOptionsForData, AzCreateFontOptionsForName, AzDestroyFontOptions, AzSkiaGetCurrentGLContext, AzCreatePathBuilder, AzReleasePathBuilder, AzPathBuilderMoveTo, AzPathBuilderLineTo, AzPathBuilderFinish, AzReleasePath}; pub mod azure_hl; diff --git a/azure.rs b/azure.rs index 9fcef0d..b7b99cd 100644 --- a/azure.rs +++ b/azure.rs @@ -386,7 +386,9 @@ pub fn AzReleaseScaledFont(aFont: AzScaledFontRef); pub fn AzDrawTargetSetTransform(aDrawTarget: AzDrawTargetRef, aTransform: *AzMatrix); -pub fn AzCreateFontOptions(aName: *c_char, aStyle: enum_AzFontStyle) -> *AzFontOptions; +pub fn AzCreateFontOptionsForData(aFontData: *u8, aFontDataSize: u32) -> *AzFontOptions; + +pub fn AzCreateFontOptionsForName(aName: *c_char, aStyle: enum_AzFontStyle) -> *AzFontOptions; pub fn AzDestroyFontOptions(aOptions: *AzFontOptions); diff --git a/include/mozilla/gfx/2D.h b/include/mozilla/gfx/2D.h index 4238202..d936dba 100644 --- a/include/mozilla/gfx/2D.h +++ b/include/mozilla/gfx/2D.h @@ -517,6 +517,8 @@ struct FontOptions { std::string mName; FontStyle mStyle; + uint8_t *mData; + uint32_t mDataSize; }; #endif diff --git a/scaled_font.rs b/scaled_font.rs index 7391e2f..fa638e1 100644 --- a/scaled_font.rs +++ b/scaled_font.rs @@ -47,6 +47,13 @@ pub mod android { pub type SkTypeface = *c_void; +#[cfg(target_os="linux")] +#[cfg(target_os="android")] +pub enum FontInfo<'a> { + NativeFont(FT_Face), + FontData(&'a Vec), +} + pub struct ScaledFont { azure_scaled_font: AzScaledFontRef, } @@ -66,10 +73,10 @@ impl ScaledFont { #[cfg(target_os="linux")] #[cfg(target_os="android")] - pub fn new(backend: BackendType, native_font: FT_Face, size: AzFloat) + pub fn new(backend: BackendType, font_info: FontInfo, size: AzFloat) -> ScaledFont { use azure::AZ_NATIVE_FONT_SKIA_FONT_FACE; - use azure::{AzCreateFontOptions, AzDestroyFontOptions}; + use azure::{AzCreateFontOptionsForData, AzCreateFontOptionsForName, AzDestroyFontOptions}; let mut azure_native_font = struct__AzNativeFont { mType: 0, @@ -79,9 +86,16 @@ impl ScaledFont { match backend { SkiaBackend => { unsafe { - // NOTE: azure style flags and freetype style flags are the same in the lowest 2 bits - let style = ((*native_font).style_flags & 3) as u32; - let options = AzCreateFontOptions((*native_font).family_name, style); + let options = match font_info { + NativeFont(native_font) => { + // NOTE: azure style flags and freetype style flags are the same in the lowest 2 bits + let style = ((*native_font).style_flags & 3) as u32; + AzCreateFontOptionsForName((*native_font).family_name, style) + }, + FontData(bytes) => { + AzCreateFontOptionsForData(bytes.as_ptr(), bytes.len() as u32) + }, + }; azure_native_font.mType = AZ_NATIVE_FONT_SKIA_FONT_FACE; azure_native_font.mFont = mem::transmute(options); let azure_native_font_ptr = &azure_native_font; diff --git a/src/gfx/2d/ScaledFontFreetype.cpp b/src/gfx/2d/ScaledFontFreetype.cpp index 20f0da6..3d29474 100644 --- a/src/gfx/2d/ScaledFontFreetype.cpp +++ b/src/gfx/2d/ScaledFontFreetype.cpp @@ -8,6 +8,7 @@ #ifdef USE_SKIA #include "SkTypeface.h" +#include "SkStream.h" #endif #include @@ -37,13 +38,19 @@ fontStyleToSkia(FontStyle aStyle) } #endif -// Ideally we want to use FT_Face here but as there is currently no way to get -// an SkTypeface from an FT_Face we do this. ScaledFontFreetype::ScaledFontFreetype(FontOptions* aFont, Float aSize) : ScaledFontBase(aSize) { #ifdef USE_SKIA - mTypeface = SkTypeface::CreateFromName(aFont->mName.c_str(), fontStyleToSkia(aFont->mStyle)); + if (aFont->mData) + { + SkStream *stream = new SkMemoryStream(aFont->mData, aFont->mDataSize, true); + mTypeface = SkTypeface::CreateFromStream(stream); + } + else + { + mTypeface = SkTypeface::CreateFromName(aFont->mName.c_str(), fontStyleToSkia(aFont->mStyle)); + } #endif }