Bug 1455848 - use paths for WR font handles on Windows. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D16896
This commit is contained in:
Lee Salzman 2019-01-17 15:45:07 -05:00
parent 7ccb4bf803
commit bd0b2ed9f0
17 changed files with 161 additions and 323 deletions

View File

@ -318,112 +318,65 @@ bool UnscaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback,
return true;
}
static bool GetDWriteName(RefPtr<IDWriteLocalizedStrings> aNames,
std::vector<WCHAR>& aOutName) {
BOOL exists = false;
UINT32 index = 0;
HRESULT hr = aNames->FindLocaleName(L"en-us", &index, &exists);
if (FAILED(hr)) {
return false;
}
if (!exists) {
// No english found, use whatever is first in the list.
index = 0;
}
UINT32 length;
hr = aNames->GetStringLength(index, &length);
if (FAILED(hr)) {
return false;
}
aOutName.resize(length + 1);
hr = aNames->GetString(index, aOutName.data(), length + 1);
return SUCCEEDED(hr);
}
static bool GetDWriteFamilyName(const RefPtr<IDWriteFontFamily>& aFamily,
std::vector<WCHAR>& aOutName) {
RefPtr<IDWriteLocalizedStrings> names;
HRESULT hr = aFamily->GetFamilyNames(getter_AddRefs(names));
if (FAILED(hr)) {
return false;
}
return GetDWriteName(names, aOutName);
}
static void GetFontFileNames(RefPtr<IDWriteFontFace> aFontFace,
std::vector<WCHAR>& aFamilyName,
std::vector<WCHAR>& aFileNames) {
MOZ_ASSERT(aFamilyName.size() >= 1 && aFamilyName.back() == 0);
static bool GetFontFileName(RefPtr<IDWriteFontFace> aFontFace,
std::vector<WCHAR>& aFileName) {
UINT32 numFiles;
HRESULT hr = aFontFace->GetFiles(&numFiles, nullptr);
if (FAILED(hr)) {
gfxCriticalNote << "Failed getting file count for font \""
<< &aFamilyName[0] << "\"";
return;
} else if (!numFiles) {
gfxCriticalNote << "No files found for font \"" << &aFamilyName[0] << "\"";
return;
}
std::vector<RefPtr<IDWriteFontFile>> files;
files.resize(numFiles);
hr = aFontFace->GetFiles(&numFiles, getter_AddRefs(files[0]));
if (FAILED(hr)) {
gfxCriticalNote << "Failed getting files for font \"" << &aFamilyName[0]
<< "\"";
return;
gfxDebug() << "Failed getting file count for WR font";
return false;
} else if (numFiles != 1) {
gfxDebug() << "Invalid file count " << numFiles << " for WR font";
return false;
}
for (auto& file : files) {
const void* key;
UINT32 keySize;
hr = file->GetReferenceKey(&key, &keySize);
if (FAILED(hr)) {
gfxCriticalNote << "Failed getting file ref key for font \""
<< &aFamilyName[0] << "\"";
return;
}
RefPtr<IDWriteFontFileLoader> loader;
hr = file->GetLoader(getter_AddRefs(loader));
if (FAILED(hr)) {
gfxCriticalNote << "Failed getting file loader for font \""
<< &aFamilyName[0] << "\"";
return;
}
RefPtr<IDWriteLocalFontFileLoader> localLoader;
loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader),
(void**)getter_AddRefs(localLoader));
if (!localLoader) {
gfxCriticalNote << "Failed querying loader interface for font \""
<< &aFamilyName[0] << "\"";
return;
}
UINT32 pathLen;
hr = localLoader->GetFilePathLengthFromKey(key, keySize, &pathLen);
if (FAILED(hr)) {
gfxCriticalNote << "Failed getting path length for font \""
<< &aFamilyName[0] << "\"";
return;
}
size_t offset = aFileNames.size();
aFileNames.resize(offset + pathLen + 1);
hr = localLoader->GetFilePathFromKey(key, keySize, &aFileNames[offset],
pathLen + 1);
if (FAILED(hr)) {
aFileNames.resize(offset);
gfxCriticalNote << "Failed getting path for font \"" << &aFamilyName[0]
<< "\"";
return;
}
MOZ_ASSERT(aFileNames.back() == 0);
DWORD attribs = GetFileAttributesW(&aFileNames[offset]);
if (attribs == INVALID_FILE_ATTRIBUTES) {
gfxCriticalNote << "sending font family \"" << &aFamilyName[0]
<< "\" with invalid file \"" << &aFileNames[offset]
<< "\"";
}
RefPtr<IDWriteFontFile> file;
hr = aFontFace->GetFiles(&numFiles, getter_AddRefs(file));
if (FAILED(hr)) {
gfxDebug() << "Failed getting file for WR font";
return false;
}
const void* key;
UINT32 keySize;
hr = file->GetReferenceKey(&key, &keySize);
if (FAILED(hr)) {
gfxDebug() << "Failed getting file ref key for WR font";
return false;
}
RefPtr<IDWriteFontFileLoader> loader;
hr = file->GetLoader(getter_AddRefs(loader));
if (FAILED(hr)) {
gfxDebug() << "Failed getting file loader for WR font";
return false;
}
RefPtr<IDWriteLocalFontFileLoader> localLoader;
loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader),
(void**)getter_AddRefs(localLoader));
if (!localLoader) {
gfxDebug() << "Failed querying loader interface for WR font";
return false;
}
UINT32 pathLen;
hr = localLoader->GetFilePathLengthFromKey(key, keySize, &pathLen);
if (FAILED(hr)) {
gfxDebug() << "Failed getting path length for WR font";
return false;
}
aFileName.resize(pathLen + 1);
hr = localLoader->GetFilePathFromKey(key, keySize, aFileName.data(),
pathLen + 1);
if (FAILED(hr) || aFileName.back() != 0) {
gfxDebug() << "Failed getting path for WR font";
return false;
}
DWORD attribs = GetFileAttributesW(aFileName.data());
if (attribs == INVALID_FILE_ATTRIBUTES) {
gfxDebug() << "Invalid file \"" << aFileName.data() << "\" for WR font";
return false;
}
aFileName.pop_back();
return true;
}
bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
@ -432,52 +385,14 @@ bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
return false;
}
RefPtr<IDWriteFontFamily> family;
HRESULT hr = mFont->GetFontFamily(getter_AddRefs(family));
if (FAILED(hr)) {
std::vector<WCHAR> fileName;
if (!GetFontFileName(mFontFace, fileName)) {
return false;
}
uint32_t index = mFontFace->GetIndex();
DWRITE_FONT_WEIGHT weight = mFont->GetWeight();
DWRITE_FONT_STRETCH stretch = mFont->GetStretch();
DWRITE_FONT_STYLE style = mFont->GetStyle();
RefPtr<IDWriteFont> match;
hr = family->GetFirstMatchingFont(weight, stretch, style,
getter_AddRefs(match));
if (FAILED(hr) || match->GetWeight() != weight ||
match->GetStretch() != stretch || match->GetStyle() != style) {
return false;
}
std::vector<WCHAR> familyName;
if (!GetDWriteFamilyName(family, familyName)) {
return false;
}
RefPtr<IDWriteFontCollection> systemFonts = Factory::GetDWriteSystemFonts();
if (!systemFonts) {
return false;
}
UINT32 idx;
BOOL exists;
hr = systemFonts->FindFamilyName(familyName.data(), &idx, &exists);
if (FAILED(hr) || !exists) {
return false;
}
// FIXME: Debugging kluge for bug 1455848. Remove once debugged!
GetFontFileNames(mFontFace, familyName, familyName);
// The style information that identifies the font can be encoded easily in
// less than 32 bits. Since the index is needed for font descriptors, only
// the family name and style information, pass along the style in the index
// data to avoid requiring a more complicated structure packing for it in
// the data payload.
uint32_t index = weight | (stretch << 16) | (style << 24);
aCb(reinterpret_cast<const uint8_t*>(familyName.data()),
familyName.size() * sizeof(WCHAR), index, aBaton);
aCb(reinterpret_cast<const uint8_t*>(fileName.data()),
fileName.size() * sizeof(WCHAR), index, aBaton);
return true;
}

View File

@ -82,9 +82,6 @@ parent:
async FlushApzRepaints();
sync GetAPZTestData() returns (APZTestData data);
// Debugging routine for bug 1455848.
async ValidateFontDescriptor(uint8_t[] desc);
async Shutdown();
sync ShutdownSync();
child:

View File

@ -226,16 +226,6 @@ static void WriteFontDescriptor(const uint8_t* aData, uint32_t aLength,
*sink->mFontKey = sink->mWrBridge->GetNextFontKey();
#ifdef XP_WIN
// FIXME: Debugging kluge for bug 1455848. Remove once debugged!
nsTArray<uint8_t> data;
data.AppendElements(aData, aLength);
sink->mWrBridge->SendValidateFontDescriptor(data);
aLength =
uint32_t(wcsnlen_s((const wchar_t*)aData, aLength / sizeof(wchar_t)) *
sizeof(wchar_t));
#endif
sink->mResources->AddFontDescriptor(
*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength),
aIndex);

View File

@ -36,10 +36,6 @@
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
#ifdef XP_WIN
# include "dwrite.h"
#endif
#ifdef MOZ_GECKO_PROFILER
# include "ProfilerMarkerPayload.h"
#endif
@ -706,49 +702,6 @@ void WebRenderBridgeParent::ObserveSharedSurfaceRelease(
}
}
// Debugging kluge for bug 1455848. Remove once debugged!
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvValidateFontDescriptor(
nsTArray<uint8_t>&& aData) {
if (mDestroyed) {
return IPC_OK();
}
#ifdef XP_WIN
nsTArray<uint8_t> data(aData);
wchar_t* family = (wchar_t*)data.Elements();
size_t remaining = data.Length() / sizeof(wchar_t);
size_t familyLength = wcsnlen_s(family, remaining);
MOZ_ASSERT(familyLength < remaining && family[familyLength] == 0);
remaining -= familyLength + 1;
wchar_t* files = family + familyLength + 1;
BOOL exists = FALSE;
if (RefPtr<IDWriteFontCollection> systemFonts =
Factory::GetDWriteSystemFonts()) {
UINT32 idx;
systemFonts->FindFamilyName(family, &idx, &exists);
}
if (!remaining) {
gfxCriticalNote << (exists ? "found" : "MISSING") << " font family \""
<< family << "\" has no files!";
}
while (remaining > 0) {
size_t fileLength = wcsnlen_s(files, remaining);
MOZ_ASSERT(fileLength < remaining && files[fileLength] == 0);
DWORD attribs = GetFileAttributesW(files);
if (!exists || attribs == INVALID_FILE_ATTRIBUTES) {
gfxCriticalNote << (exists ? "found" : "MISSING") << " font family \""
<< family << "\" has "
<< (attribs == INVALID_FILE_ATTRIBUTES ? "INVALID"
: "valid")
<< "(" << hexa(attribs) << ")"
<< " file \"" << files << "\"";
}
remaining -= fileLength + 1;
files += fileLength + 1;
}
#endif
return IPC_OK();
}
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvUpdateResources(
nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<RefCountedShmem>&& aSmallShmems,

View File

@ -125,9 +125,6 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
nsTArray<WebRenderParentCommand>&& commands) override;
mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
mozilla::ipc::IPCResult RecvValidateFontDescriptor(
nsTArray<uint8_t>&& aData) override;
mozilla::ipc::IPCResult RecvSetLayersObserverEpoch(
const LayersObserverEpoch& aChildEpoch) override;

View File

@ -23,7 +23,7 @@ default-features = false
features = ["capture", "serialize_program"]
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.7"
dwrote = "0.8"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.6"

View File

@ -1,4 +1,10 @@
use std::ffi::{CStr, CString};
#[cfg(not(target_os = "macos"))]
use std::ffi::OsString;
#[cfg(target_os = "windows")]
use std::os::windows::ffi::OsStringExt;
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
use std::os::unix::ffi::OsStringExt;
use std::io::Cursor;
use std::{mem, slice, ptr, env};
use std::path::PathBuf;
@ -28,9 +34,6 @@ use rayon;
use euclid::SideOffsets2D;
use nsstring::nsAString;
#[cfg(target_os = "windows")]
use dwrote::{FontDescriptor, FontWeight, FontStretch, FontStyle};
#[cfg(target_os = "macos")]
use core_foundation::string::CFString;
#[cfg(target_os = "macos")]
@ -1713,11 +1716,9 @@ fn read_font_descriptor(
index: u32
) -> NativeFontHandle {
let wchars = bytes.convert_into_vec::<u16>();
FontDescriptor {
family_name: String::from_utf16(&wchars).unwrap(),
weight: FontWeight::from_u32(index & 0xffff),
stretch: FontStretch::from_u32((index >> 16) & 0xff),
style: FontStyle::from_u32((index >> 24) & 0xff),
NativeFontHandle {
path: PathBuf::from(OsString::from_wide(&wchars)),
index,
}
}
@ -1737,9 +1738,9 @@ fn read_font_descriptor(
bytes: &mut WrVecU8,
index: u32
) -> NativeFontHandle {
let cstr = CString::new(bytes.flush_into_vec()).unwrap();
let chars = bytes.flush_into_vec();
NativeFontHandle {
pathname: String::from(cstr.to_str().unwrap()),
path: PathBuf::from(OsString::from_vec(chars)),
index,
}
}

View File

@ -30,6 +30,8 @@ use foreign_types::ForeignType;
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
use std::ffi::CString;
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
use std::os::unix::ffi::OsStrExt;
/// Local print-debugging utility
macro_rules! dlog {
@ -655,9 +657,8 @@ impl Moz2dBlobImageHandler {
fn prepare_request(&self, blob: &[u8], resources: &BlobImageResources) {
#[cfg(target_os = "windows")]
fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
let system_fc = dwrote::FontCollection::system();
let font = system_fc.get_font_from_descriptor(handle).unwrap();
let face = font.create_font_face();
let file = dwrote::FontFile::new_from_path(&handle.path).unwrap();
let face = file.create_face(handle.index, dwrote::DWRITE_FONT_SIMULATIONS_NONE).unwrap();
unsafe { AddNativeFontHandle(key, face.as_ptr() as *mut c_void, 0) };
}
@ -668,7 +669,7 @@ impl Moz2dBlobImageHandler {
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) {
let cstr = CString::new(handle.pathname.clone()).unwrap();
let cstr = CString::new(handle.path.as_os_str().as_bytes()).unwrap();
unsafe { AddNativeFontHandle(key, cstr.as_ptr() as *mut c_void, handle.index) };
}

View File

@ -81,7 +81,7 @@ freetype = { version = "0.4", default-features = false }
libc = "0.2"
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.7"
dwrote = "0.8"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.6"

View File

@ -319,7 +319,8 @@ impl FontContext {
pub fn add_native_font(&mut self, font_key: &FontKey, native_font_handle: NativeFontHandle) {
if !self.faces.contains_key(&font_key) {
let file = FontFile::Pathname(CString::new(native_font_handle.pathname).unwrap());
let cstr = CString::new(native_font_handle.path.as_os_str().to_str().unwrap()).unwrap();
let file = FontFile::Pathname(cstr);
let index = native_font_handle.index;
if let Some(face) = new_ft_face(font_key, self.lib, &file, index) {
self.faces.insert(*font_key, FontFace { file, index, face, mm_var: ptr::null_mut() });
@ -965,6 +966,7 @@ impl Drop for FontContext {
impl<'a> Into<pf_freetype::FontDescriptor> for NativeFontHandleWrapper<'a> {
fn into(self) -> pf_freetype::FontDescriptor {
let NativeFontHandleWrapper(font_handle) = self;
pf_freetype::FontDescriptor::new(font_handle.pathname.clone().into(), font_handle.index)
let str = font_handle.path.as_os_str().to_str().unwrap();
pf_freetype::FontDescriptor::new(str.into(), font_handle.index)
}
}

View File

@ -3,13 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{FontInstanceFlags, FontKey, FontRenderMode, FontVariation};
use api::{ColorU, GlyphDimensions};
use api::{ColorU, GlyphDimensions, NativeFontHandle};
use dwrote;
use gamma_lut::ColorLut;
use glyph_rasterizer::{FontInstance, FontTransform, GlyphKey};
use internal_types::{FastHashMap, ResourceCacheError};
use std::collections::hash_map::Entry;
use std::sync::Arc;
cfg_if! {
if #[cfg(feature = "pathfinder")] {
use pathfinder_font_renderer::{PathfinderComPtr, IDWriteFontFace};
@ -30,8 +31,14 @@ lazy_static! {
};
}
struct FontFace {
file: dwrote::FontFile,
index: u32,
face: dwrote::FontFace,
}
pub struct FontContext {
fonts: FastHashMap<FontKey, dwrote::FontFace>,
fonts: FastHashMap<FontKey, FontFace>,
variations: FastHashMap<(FontKey, dwrote::DWRITE_FONT_SIMULATIONS, Vec<FontVariation>), dwrote::FontFace>,
#[cfg(not(feature = "pathfinder"))]
gamma_luts: FastHashMap<(u16, u16), GammaLut>,
@ -110,68 +117,46 @@ impl FontContext {
self.fonts.contains_key(font_key)
}
fn add_font_descriptor(&mut self, font_key: &FontKey, desc: &dwrote::FontDescriptor) {
let system_fc = dwrote::FontCollection::get_system(false);
if let Some(font) = system_fc.get_font_from_descriptor(desc) {
let face = font.create_font_face();
let file = face.get_files().pop().unwrap();
let index = face.get_index();
self.fonts.insert(*font_key, FontFace { file, index, face });
}
}
pub fn add_raw_font(&mut self, font_key: &FontKey, data: Arc<Vec<u8>>, index: u32) {
if self.fonts.contains_key(font_key) {
return;
}
if let Some(font_file) = dwrote::FontFile::new_from_data(data) {
let face = font_file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE);
self.fonts.insert(*font_key, face);
} else {
// XXX add_raw_font needs to have a way to return an error
debug!("DWrite WR failed to load font from data, using Arial instead");
self.add_native_font(font_key, DEFAULT_FONT_DESCRIPTOR.clone());
}
}
pub fn load_system_font(font_handle: &dwrote::FontDescriptor, update: bool) -> Result<dwrote::Font, String> {
let system_fc = dwrote::FontCollection::get_system(update);
// A version of get_font_from_descriptor() that panics early to help with bug 1455848
if let Some(family) = system_fc.get_font_family_by_name(&font_handle.family_name) {
let font = family.get_first_matching_font(font_handle.weight, font_handle.stretch, font_handle.style);
// Exact matches only here
if font.weight() == font_handle.weight &&
font.stretch() == font_handle.stretch &&
font.style() == font_handle.style
{
Ok(font)
} else {
// We can't depend on the family's fonts being in a particular order, so the first match may not
// be an exact match, even though it is sufficiently close to be a match. As a slower fallback,
// try looking through all of the fonts in the family for an exact match. The caller should have
// verified that an exact match exists so that this search shouldn't fail.
(0 .. family.get_font_count()).filter_map(|idx| {
let alt = family.get_font(idx);
if alt.weight() == font_handle.weight &&
alt.stretch() == font_handle.stretch &&
alt.style() == font_handle.style
{
Some(alt)
} else {
None
}
}).next().ok_or_else(|| {
format!("font mismatch for descriptor {:?} {:?}", font_handle, font.to_descriptor())
})
if let Some(file) = dwrote::FontFile::new_from_data(data) {
if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
self.fonts.insert(*font_key, FontFace { file, index, face });
return;
}
} else {
Err(format!("missing font family for descriptor {:?}", font_handle))
}
// XXX add_raw_font needs to have a way to return an error
debug!("DWrite WR failed to load font from data, using Arial instead");
self.add_font_descriptor(font_key, &DEFAULT_FONT_DESCRIPTOR);
}
pub fn add_native_font(&mut self, font_key: &FontKey, font_handle: dwrote::FontDescriptor) {
pub fn add_native_font(&mut self, font_key: &FontKey, font_handle: NativeFontHandle) {
if self.fonts.contains_key(font_key) {
return;
}
// First try to load the font without updating the system font collection.
// If the font can't be found, try again after updating the system font collection.
// If even that fails, panic...
let font = Self::load_system_font(&font_handle, false).unwrap_or_else(|_| {
Self::load_system_font(&font_handle, true).unwrap()
});
let face = font.create_font_face();
self.fonts.insert(*font_key, face);
if let Some(file) = dwrote::FontFile::new_from_path(font_handle.pathname) {
let index = font_handle.index;
if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
self.fonts.insert(*font_key, FontFace { file, index, face });
return;
}
}
// XXX add_native_font needs to have a way to return an error
debug!("DWrite WR failed to load font from path, using Arial instead");
self.add_font_descriptor(font_key, &DEFAULT_FONT_DESCRIPTOR);
}
pub fn delete_font(&mut self, font_key: &FontKey) {
@ -216,7 +201,7 @@ impl FontContext {
) -> &dwrote::FontFace {
if !font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) &&
font.variations.is_empty() {
return self.fonts.get(&font.font_key).unwrap();
return &self.fonts.get(&font.font_key).unwrap().face;
}
let sims = if font.flags.contains(FontInstanceFlags::SYNTHETIC_BOLD) {
dwrote::DWRITE_FONT_SIMULATIONS_BOLD
@ -228,7 +213,7 @@ impl FontContext {
Entry::Vacant(entry) => {
let normal_face = self.fonts.get(&font.font_key).unwrap();
if !font.variations.is_empty() {
if let Some(var_face) = normal_face.create_font_face_with_variations(
if let Some(var_face) = normal_face.face.create_font_face_with_variations(
sims,
&font.variations.iter().map(|var| {
dwrote::DWRITE_FONT_AXIS_VALUE {
@ -241,7 +226,10 @@ impl FontContext {
return entry.insert(var_face);
}
}
entry.insert(normal_face.create_font_face_with_simulations(sims))
let var_face = normal_face.file
.create_face(normal_face.index, sims)
.unwrap_or_else(|_| normal_face.face.clone());
entry.insert(var_face)
}
}
}
@ -315,7 +303,7 @@ impl FontContext {
}
pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option<u32> {
let face = self.fonts.get(&font_key).unwrap();
let face = &self.fonts.get(&font_key).unwrap().face;
let indices = face.get_glyph_indices(&[ch as u32]);
indices.first().map(|idx| *idx as u32)
}
@ -547,12 +535,12 @@ impl FontContext {
#[cfg(feature = "pathfinder")]
impl<'a> From<NativeFontHandleWrapper<'a>> for PathfinderComPtr<IDWriteFontFace> {
fn from(font_handle: NativeFontHandleWrapper<'a>) -> Self {
let system_fc = ::dwrote::FontCollection::system();
let font = match system_fc.get_font_from_descriptor(&font_handle.0) {
Some(font) => font,
None => panic!("missing descriptor {:?}", font_handle.0),
};
let face = font.create_font_face();
unsafe { PathfinderComPtr::new(face.as_ptr()) }
if let Some(file) = dwrote::FontFile::new_from_path(font_handle.0.pathname) {
let index = font_handle.0.index;
if let Ok(face) = file.create_face(index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) {
return unsafe { PathfinderComPtr::new(face.as_ptr()) };
}
}
panic!("missing font {:?}", font_handle.0)
}
}

View File

@ -30,6 +30,3 @@ wr_malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of" }
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.6"
core-graphics = "0.17.1"
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.7"

View File

@ -7,22 +7,22 @@ use app_units::Au;
use core_foundation::string::CFString;
#[cfg(target_os = "macos")]
use core_graphics::font::CGFont;
#[cfg(target_os = "windows")]
pub use dwrote::FontDescriptor as NativeFontHandle;
#[cfg(target_os = "macos")]
use serde::de::{self, Deserialize, Deserializer};
#[cfg(target_os = "macos")]
use serde::ser::{Serialize, Serializer};
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
#[cfg(not(target_os = "macos"))]
use std::path::PathBuf;
use std::sync::Arc;
use {ColorU, IdNamespace, LayoutPoint};
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[cfg(not(target_os = "macos"))]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NativeFontHandle {
pub pathname: String,
pub path: PathBuf,
pub index: u32,
}

View File

@ -27,8 +27,6 @@ extern crate core_foundation;
extern crate core_graphics;
#[macro_use]
extern crate derive_more;
#[cfg(target_os = "windows")]
extern crate dwrote;
pub extern crate euclid;
#[cfg(feature = "ipc")]
extern crate ipc_channel;

View File

@ -39,7 +39,7 @@ headless = [ "osmesa-sys", "osmesa-src" ]
pathfinder = [ "webrender/pathfinder" ]
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.7"
dwrote = "0.8"
mozangle = {version = "0.1.5", features = ["egl"]}
[target.'cfg(all(unix, not(target_os = "android")))'.dependencies]

View File

@ -391,15 +391,12 @@ impl Wrench {
#[cfg(target_os = "windows")]
pub fn font_key_from_name(&mut self, font_name: &str) -> FontKey {
let system_fc = dwrote::FontCollection::system();
let family = system_fc.get_font_family_by_name(font_name).unwrap();
let font = family.get_first_matching_font(
dwrote::FontWeight::Regular,
dwrote::FontStretch::Normal,
dwrote::FontStyle::Normal,
);
let descriptor = font.to_descriptor();
self.font_key_from_native_handle(&descriptor)
self.font_key_from_properties(
font_name,
dwrote::FontWeight::Regular.to_u32(),
dwrote::FontStretch::Normal.to_u32(),
dwrote::FontStyle::Normal.to_u32(),
)
}
#[cfg(target_os = "windows")]
@ -413,14 +410,26 @@ impl Wrench {
let weight = dwrote::FontWeight::from_u32(weight);
let style = dwrote::FontStyle::from_u32(style);
let stretch = dwrote::FontStretch::from_u32(stretch);
let desc = dwrote::FontDescriptor {
family_name: family.to_owned(),
weight,
style,
stretch,
};
self.font_key_from_native_handle(&desc)
let system_fc = dwrote::FontCollection::system();
if let Some(font) = system_fc.get_font_from_descriptor(&desc) {
let face = font.create_font_face();
let files = face.get_files();
if files.len() == 1 {
if let Some(path) = files[0].get_font_file_path() {
return self.font_key_from_native_handle(&NativeFontHandle {
path,
index: face.get_index(),
});
}
}
}
panic!("failed loading font from properties {:?}", desc)
}
#[cfg(all(unix, not(target_os = "android")))]

View File

@ -268,19 +268,6 @@ fn write_stacking_context(
yaml_node(parent, "filters", Yaml::Array(filters));
}
#[cfg(target_os = "windows")]
fn native_font_handle_to_yaml(
_rsrc: &mut ResourceGenerator,
handle: &NativeFontHandle,
parent: &mut yaml_rust::yaml::Hash,
_: &mut Option<PathBuf>,
) {
str_node(parent, "family", &handle.family_name);
u32_node(parent, "weight", handle.weight.to_u32());
u32_node(parent, "style", handle.style.to_u32());
u32_node(parent, "stretch", handle.stretch.to_u32());
}
#[cfg(target_os = "macos")]
fn native_font_handle_to_yaml(
rsrc: &mut ResourceGenerator,
@ -307,14 +294,17 @@ fn native_font_handle_to_yaml(
path_node(parent, "font", &path);
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[cfg(not(target_os = "macos"))]
fn native_font_handle_to_yaml(
_rsrc: &mut ResourceGenerator,
handle: &NativeFontHandle,
parent: &mut yaml_rust::yaml::Hash,
_: &mut Option<PathBuf>,
) {
str_node(parent, "font", &handle.pathname);
str_node(parent, "font", handle.path.as_os_str().to_str().unwrap());
if handle.index != 0 {
u32_node(parent, "font-index", handle.index);
}
}
fn radial_gradient_to_yaml(