mirror of
https://github.com/servo/servo.git
synced 2025-08-09 23:45:35 +01:00
DirectWrite font backend for Windows
This commit is contained in:
parent
d16f312464
commit
db357b0334
9 changed files with 572 additions and 179 deletions
|
@ -2,88 +2,56 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use gdi32;
|
||||
use app_units::Au;
|
||||
use servo_atoms::Atom;
|
||||
use std::ffi::OsString;
|
||||
use std::io::Error;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::ptr;
|
||||
use serde;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Mutex;
|
||||
use webrender_traits::NativeFontHandle;
|
||||
use winapi::{DWORD, LF_FACESIZE, LOGFONTW, OUT_TT_ONLY_PRECIS, WCHAR};
|
||||
|
||||
const GDI_ERROR: DWORD = 0xffffffff;
|
||||
use dwrote::{Font};
|
||||
use platform::windows::font_list::{descriptor_from_atom, font_from_atom};
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct FontTemplateData {
|
||||
pub bytes: Vec<u8>,
|
||||
pub bytes: Option<Vec<u8>>,
|
||||
pub identifier: Atom,
|
||||
}
|
||||
|
||||
impl FontTemplateData {
|
||||
pub fn new(identifier: Atom,
|
||||
font_data: Option<Vec<u8>>) -> Result<FontTemplateData, Error> {
|
||||
let bytes = match font_data {
|
||||
Some(bytes) => {
|
||||
bytes
|
||||
},
|
||||
None => {
|
||||
assert!(identifier.len() < LF_FACESIZE);
|
||||
let name = OsString::from(identifier.as_ref());
|
||||
let buffer: Vec<WCHAR> = name.encode_wide().collect();
|
||||
let mut string: [WCHAR; LF_FACESIZE] = [0; LF_FACESIZE];
|
||||
|
||||
for (src, dest) in buffer.iter().zip(string.iter_mut()) {
|
||||
*dest = *src;
|
||||
}
|
||||
|
||||
let config = LOGFONTW {
|
||||
lfHeight: 0,
|
||||
lfWidth: 0,
|
||||
lfEscapement: 0,
|
||||
lfOrientation: 0,
|
||||
lfWeight: 0,
|
||||
lfItalic: 0,
|
||||
lfUnderline: 0,
|
||||
lfStrikeOut: 0,
|
||||
lfCharSet: 0,
|
||||
lfOutPrecision: OUT_TT_ONLY_PRECIS as u8,
|
||||
lfClipPrecision: 0,
|
||||
lfQuality: 0,
|
||||
lfPitchAndFamily: 0,
|
||||
lfFaceName: string,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let hdc = gdi32::CreateCompatibleDC(ptr::null_mut());
|
||||
let hfont = gdi32::CreateFontIndirectW(&config as *const _);
|
||||
gdi32::SelectObject(hdc, hfont as *mut _);
|
||||
let size = gdi32::GetFontData(hdc, 0, 0, ptr::null_mut(), 0);
|
||||
assert!(size != GDI_ERROR);
|
||||
let mut buffer: Vec<u8> = vec![0; size as usize];
|
||||
let actual_size = gdi32::GetFontData(hdc, 0, 0, buffer.as_mut_ptr() as *mut _, size);
|
||||
assert!(actual_size == size);
|
||||
gdi32::DeleteDC(hdc);
|
||||
gdi32::DeleteObject(hfont as *mut _);
|
||||
buffer
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
font_data: Option<Vec<u8>>) -> Result<FontTemplateData, io::Error> {
|
||||
Ok(FontTemplateData {
|
||||
bytes: bytes,
|
||||
bytes: font_data,
|
||||
identifier: identifier,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn bytes(&self) -> Vec<u8> {
|
||||
self.bytes.clone()
|
||||
if self.bytes.is_some() {
|
||||
self.bytes.as_ref().unwrap().clone()
|
||||
} else {
|
||||
let font = font_from_atom(&self.identifier);
|
||||
let face = font.create_font_face();
|
||||
let files = face.get_files();
|
||||
assert!(files.len() > 0);
|
||||
|
||||
files[0].get_font_file_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_if_in_memory(&self) -> Option<Vec<u8>> {
|
||||
Some(self.bytes())
|
||||
self.bytes.clone()
|
||||
}
|
||||
|
||||
pub fn native_font(&self) -> Option<NativeFontHandle> {
|
||||
None
|
||||
if self.bytes.is_some() {
|
||||
panic!("Can't create fonts yet");
|
||||
}
|
||||
|
||||
let descriptor = descriptor_from_atom(&self.identifier);
|
||||
Some(descriptor)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue