Skip to content

Commit

Permalink
Add glyph pair kerning bindings (#55)
Browse files Browse the repository at this point in the history
* Add kerning pair bindings

Signed-off-by: crbrz <[email protected]>

* Use cached IDWriteFontFace1

Signed-off-by: crbrz <[email protected]>

* Fixed build warnings

Signed-off-by: crbrz <[email protected]>

---------

Signed-off-by: crbrz <[email protected]>
  • Loading branch information
crbrz authored Aug 17, 2024
1 parent 6d44068 commit f2f644d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/com_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,6 @@ where
}

unsafe fn destroy(thing: *mut Interface) {
Box::from_raw(thing as *mut ComRepr<Self, Self::Vtbl>);
let _ = Box::from_raw(thing as *mut ComRepr<Self, Self::Vtbl>);
}
}
53 changes: 49 additions & 4 deletions src/font_face.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use winapi::um::dwrite::{DWRITE_GLYPH_OFFSET, DWRITE_MATRIX, DWRITE_RENDERING_MO
use winapi::um::dwrite::{DWRITE_RENDERING_MODE_DEFAULT, DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC};
use winapi::um::dwrite_1::IDWriteFontFace1;
use winapi::um::dwrite_3::{IDWriteFontFace5, IDWriteFontResource, DWRITE_FONT_AXIS_VALUE};
use winapi::Interface;
use wio::com::ComPtr;

use super::{DWriteFactory, DefaultDWriteRenderParams, FontFile, FontMetrics};
Expand All @@ -30,6 +31,7 @@ use crate::outline_builder::OutlineBuilder;

pub struct FontFace {
native: UnsafeCell<ComPtr<IDWriteFontFace>>,
face1: UnsafeCell<Option<ComPtr<IDWriteFontFace1>>>,
face5: UnsafeCell<Option<ComPtr<IDWriteFontFace5>>>,
}

Expand All @@ -38,6 +40,7 @@ impl FontFace {
let cell = UnsafeCell::new(native);
FontFace {
native: cell,
face1: UnsafeCell::new(None),
face5: UnsafeCell::new(None),
}
}
Expand Down Expand Up @@ -99,7 +102,7 @@ impl FontFace {

pub fn metrics(&self) -> FontMetrics {
unsafe {
let font_1: Option<ComPtr<IDWriteFontFace1>> = (*self.native.get()).cast().ok();
let font_1 = self.get_face1();
match font_1 {
None => {
let mut metrics = mem::zeroed();
Expand Down Expand Up @@ -286,6 +289,34 @@ impl FontFace {
}
}

pub fn has_kerning_pairs(&self) -> bool {
unsafe {
match self.get_face1() {
Some(face1) => face1.HasKerningPairs() == TRUE,
None => false,
}
}
}

pub fn get_glyph_pair_kerning_adjustment(&self, first_glyph: u16, second_glyph: u16) -> i32 {
unsafe {
match self.get_face1() {
Some(face1) => {
let mut adjustments = [0; 2];
let hr = face1.GetKerningPairAdjustments(
2,
[first_glyph, second_glyph].as_ptr(),
adjustments.as_mut_ptr(),
);
assert_eq!(hr, S_OK);

adjustments[0]
}
None => 0,
}
}
}

#[inline]
pub fn get_type(&self) -> FontFaceType {
unsafe {
Expand All @@ -307,12 +338,25 @@ impl FontFace {
unsafe { (*self.native.get()).GetIndex() }
}

#[inline]
unsafe fn get_face1(&self) -> Option<ComPtr<IDWriteFontFace1>> {
self.get_interface(&self.face1)
}

#[inline]
unsafe fn get_face5(&self) -> Option<ComPtr<IDWriteFontFace5>> {
if (*self.face5.get()).is_none() {
*self.face5.get() = (*self.native.get()).cast().ok()
self.get_interface(&self.face5)
}

#[inline]
unsafe fn get_interface<I: Interface>(
&self,
interface: &UnsafeCell<Option<ComPtr<I>>>,
) -> Option<ComPtr<I>> {
if (*interface.get()).is_none() {
*interface.get() = (*self.native.get()).cast().ok()
}
(*self.face5.get()).clone()
(*interface.get()).clone()
}

pub fn has_variations(&self) -> bool {
Expand Down Expand Up @@ -358,6 +402,7 @@ impl Clone for FontFace {
unsafe {
FontFace {
native: UnsafeCell::new((*self.native.get()).clone()),
face1: UnsafeCell::new(None),
face5: UnsafeCell::new(None),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/font_file_loader_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ unsafe impl Sync for FontFileLoaderWrapper {}

lazy_static! {
static ref FONT_FILE_STREAM_MAP: Mutex<HashMap<usize, FontFileStreamPtr>> =
{ Mutex::new(HashMap::new()) };
Mutex::new(HashMap::new());
static ref FONT_FILE_LOADER: Mutex<FontFileLoaderWrapper> = {
unsafe {
let ffl_native = FontFileLoader::new();
Expand Down
6 changes: 1 addition & 5 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ lazy_static! {
locale
}
};
static ref EN_US_LOCALE: Vec<wchar_t> = { OsStr::new("en-us").to_wide_null() };
static ref EN_US_LOCALE: Vec<wchar_t> = OsStr::new("en-us").to_wide_null();
}

pub fn get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> String {
Expand Down Expand Up @@ -51,17 +51,13 @@ pub fn get_locale_string(strings: &mut ComPtr<IDWriteLocalizedStrings>) -> Strin
// ToWide from https://github.com/retep998/wio-rs/blob/master/src/wide.rs

pub trait ToWide {
fn to_wide(&self) -> Vec<u16>;
fn to_wide_null(&self) -> Vec<u16>;
}

impl<T> ToWide for T
where
T: AsRef<OsStr>,
{
fn to_wide(&self) -> Vec<u16> {
self.as_ref().encode_wide().collect()
}
fn to_wide_null(&self) -> Vec<u16> {
self.as_ref().encode_wide().chain(Some(0)).collect()
}
Expand Down

0 comments on commit f2f644d

Please sign in to comment.