summaryrefslogtreecommitdiffstats
path: root/third_party/rust/dwrote/src/font_collection_impl.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/dwrote/src/font_collection_impl.rs
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/dwrote/src/font_collection_impl.rs')
-rw-r--r--third_party/rust/dwrote/src/font_collection_impl.rs157
1 files changed, 157 insertions, 0 deletions
diff --git a/third_party/rust/dwrote/src/font_collection_impl.rs b/third_party/rust/dwrote/src/font_collection_impl.rs
new file mode 100644
index 0000000000..8a9d68e890
--- /dev/null
+++ b/third_party/rust/dwrote/src/font_collection_impl.rs
@@ -0,0 +1,157 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+// A temporary custom font collection that exists solely for the face-to-font mapping to work.
+
+use std::mem;
+use std::sync::atomic::AtomicUsize;
+use winapi::ctypes::c_void;
+use winapi::shared::guiddef::REFIID;
+use winapi::shared::minwindef::{BOOL, FALSE, TRUE, ULONG};
+use winapi::shared::winerror::{E_INVALIDARG, S_OK};
+use winapi::um::dwrite::IDWriteFactory;
+use winapi::um::dwrite::IDWriteFontCollectionLoader;
+use winapi::um::dwrite::IDWriteFontCollectionLoaderVtbl;
+use winapi::um::dwrite::IDWriteFontFile;
+use winapi::um::dwrite::IDWriteFontFileEnumerator;
+use winapi::um::dwrite::IDWriteFontFileEnumeratorVtbl;
+use winapi::um::unknwnbase::{IUnknown, IUnknownVtbl};
+use winapi::um::winnt::HRESULT;
+use wio::com::ComPtr;
+
+use crate::com_helpers::Com;
+use crate::FontFile;
+
+static FONT_COLLECTION_LOADER_VTBL: IDWriteFontCollectionLoaderVtbl =
+ IDWriteFontCollectionLoaderVtbl {
+ parent: implement_iunknown!(static IDWriteFontCollectionLoader,
+ CustomFontCollectionLoaderImpl),
+ CreateEnumeratorFromKey: CustomFontCollectionLoaderImpl_CreateEnumeratorFromKey,
+ };
+
+#[repr(C)]
+pub struct CustomFontCollectionLoaderImpl {
+ // NB: This must be the first field.
+ _refcount: AtomicUsize,
+ font_files: Vec<ComPtr<IDWriteFontFile>>,
+}
+
+impl Com<IDWriteFontCollectionLoader> for CustomFontCollectionLoaderImpl {
+ type Vtbl = IDWriteFontCollectionLoaderVtbl;
+ #[inline]
+ fn vtbl() -> &'static IDWriteFontCollectionLoaderVtbl {
+ &FONT_COLLECTION_LOADER_VTBL
+ }
+}
+
+impl Com<IUnknown> for CustomFontCollectionLoaderImpl {
+ type Vtbl = IUnknownVtbl;
+ #[inline]
+ fn vtbl() -> &'static IUnknownVtbl {
+ &FONT_COLLECTION_LOADER_VTBL.parent
+ }
+}
+
+impl CustomFontCollectionLoaderImpl {
+ pub fn new(font_files: &[FontFile]) -> ComPtr<IDWriteFontCollectionLoader> {
+ unsafe {
+ ComPtr::from_raw(
+ CustomFontCollectionLoaderImpl {
+ _refcount: AtomicUsize::new(1),
+ font_files: font_files.iter().map(|file| file.as_com_ptr()).collect(),
+ }
+ .into_interface(),
+ )
+ }
+ }
+}
+
+#[allow(non_snake_case)]
+unsafe extern "system" fn CustomFontCollectionLoaderImpl_CreateEnumeratorFromKey(
+ this: *mut IDWriteFontCollectionLoader,
+ _: *mut IDWriteFactory,
+ _: *const c_void,
+ _: u32,
+ out_enumerator: *mut *mut IDWriteFontFileEnumerator,
+) -> HRESULT {
+ let this = CustomFontCollectionLoaderImpl::from_interface(this);
+ let enumerator = CustomFontFileEnumeratorImpl::new((*this).font_files.clone());
+ let enumerator = ComPtr::<IDWriteFontFileEnumerator>::from_raw(enumerator.into_interface());
+ *out_enumerator = enumerator.as_raw();
+ mem::forget(enumerator);
+ S_OK
+}
+
+#[repr(C)]
+struct CustomFontFileEnumeratorImpl {
+ // NB(pcwalton): This must be the first field.
+ _refcount: AtomicUsize,
+ font_files: Vec<ComPtr<IDWriteFontFile>>,
+ index: isize,
+}
+
+impl Com<IDWriteFontFileEnumerator> for CustomFontFileEnumeratorImpl {
+ type Vtbl = IDWriteFontFileEnumeratorVtbl;
+ #[inline]
+ fn vtbl() -> &'static IDWriteFontFileEnumeratorVtbl {
+ &FONT_FILE_ENUMERATOR_VTBL
+ }
+}
+
+impl Com<IUnknown> for CustomFontFileEnumeratorImpl {
+ type Vtbl = IUnknownVtbl;
+ #[inline]
+ fn vtbl() -> &'static IUnknownVtbl {
+ &FONT_FILE_ENUMERATOR_VTBL.parent
+ }
+}
+
+static FONT_FILE_ENUMERATOR_VTBL: IDWriteFontFileEnumeratorVtbl = IDWriteFontFileEnumeratorVtbl {
+ parent: implement_iunknown!(static IDWriteFontFileEnumerator, CustomFontFileEnumeratorImpl),
+ GetCurrentFontFile: CustomFontFileEnumeratorImpl_GetCurrentFontFile,
+ MoveNext: CustomFontFileEnumeratorImpl_MoveNext,
+};
+
+impl CustomFontFileEnumeratorImpl {
+ pub fn new(font_files: Vec<ComPtr<IDWriteFontFile>>) -> CustomFontFileEnumeratorImpl {
+ CustomFontFileEnumeratorImpl {
+ _refcount: AtomicUsize::new(1),
+ font_files,
+ index: -1,
+ }
+ }
+}
+
+#[allow(non_snake_case)]
+unsafe extern "system" fn CustomFontFileEnumeratorImpl_GetCurrentFontFile(
+ this: *mut IDWriteFontFileEnumerator,
+ out_font_file: *mut *mut IDWriteFontFile,
+) -> HRESULT {
+ let this = CustomFontFileEnumeratorImpl::from_interface(this);
+ if (*this).index < 0 || (*this).index >= (*this).font_files.len() as isize {
+ return E_INVALIDARG;
+ }
+ let new_font_file = (*this).font_files[(*this).index as usize].clone();
+ *out_font_file = new_font_file.as_raw();
+ mem::forget(new_font_file);
+ S_OK
+}
+
+#[allow(non_snake_case)]
+unsafe extern "system" fn CustomFontFileEnumeratorImpl_MoveNext(
+ this: *mut IDWriteFontFileEnumerator,
+ has_current_file: *mut BOOL,
+) -> HRESULT {
+ let this = CustomFontFileEnumeratorImpl::from_interface(this);
+ let font_file_count = (*this).font_files.len() as isize;
+ if (*this).index < font_file_count {
+ (*this).index += 1
+ }
+ *has_current_file = if (*this).index >= 0 && (*this).index < font_file_count {
+ TRUE
+ } else {
+ FALSE
+ };
+ S_OK
+}