summaryrefslogtreecommitdiffstats
path: root/third_party/rust/dwrote/src/lib.rs
blob: b392bcaf5a882bc2d964ad6f4ddb2814af839409 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* 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/. */

#![allow(non_upper_case_globals)]

#[cfg(feature = "serde_serialization")]
extern crate serde;
#[cfg_attr(feature = "serde_serialization", macro_use)]
#[cfg(feature = "serde_serialization")]
extern crate serde_derive;

#[macro_use]
extern crate lazy_static;
extern crate libc;
extern crate winapi;

include!("types.rs");

use std::ffi::CString;
use std::ptr;
use winapi::Interface;
use winapi::shared::guiddef::REFIID;
use winapi::shared::winerror::S_OK;
use winapi::um::dwrite::DWRITE_FACTORY_TYPE;
use winapi::um::dwrite::DWRITE_FACTORY_TYPE_SHARED;
use winapi::um::dwrite::IDWriteFactory;
use winapi::um::dwrite::IDWriteRenderingParams;
use winapi::um::unknwnbase::IUnknown;
use winapi::um::winnt::LPCSTR;

pub use winapi::um::winnt::HRESULT;

mod helpers;
use helpers::ToWide;
use std::os::raw::c_void;

#[cfg(test)]
mod test;

// We still use the DWrite structs for things like metrics; re-export them
// here
pub use winapi::shared::windef::RECT;
pub use winapi::um::dcommon::DWRITE_MEASURING_MODE;
pub use winapi::um::dcommon::{
    DWRITE_MEASURING_MODE_GDI_CLASSIC, DWRITE_MEASURING_MODE_GDI_NATURAL,
    DWRITE_MEASURING_MODE_NATURAL,
};
pub use winapi::um::dwrite::DWRITE_FONT_METRICS as FontMetrics0;
pub use winapi::um::dwrite::DWRITE_FONT_SIMULATIONS;
pub use winapi::um::dwrite::DWRITE_GLYPH_OFFSET as GlyphOffset;
pub use winapi::um::dwrite::DWRITE_RENDERING_MODE;
pub use winapi::um::dwrite::DWRITE_TEXTURE_TYPE;
pub use winapi::um::dwrite::{DWRITE_TEXTURE_ALIASED_1x1, DWRITE_TEXTURE_CLEARTYPE_3x1};
pub use winapi::um::dwrite::{
    DWRITE_FONT_SIMULATIONS_BOLD, DWRITE_FONT_SIMULATIONS_NONE, DWRITE_FONT_SIMULATIONS_OBLIQUE,
};
pub use winapi::um::dwrite::{DWRITE_GLYPH_RUN, DWRITE_MATRIX};
pub use winapi::um::dwrite::{
    DWRITE_RENDERING_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC,
    DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL,
    DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, DWRITE_RENDERING_MODE_DEFAULT,
    DWRITE_RENDERING_MODE_GDI_CLASSIC, DWRITE_RENDERING_MODE_GDI_NATURAL,
    DWRITE_RENDERING_MODE_NATURAL, DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC,
    DWRITE_RENDERING_MODE_OUTLINE,
};
pub use winapi::um::dwrite_1::DWRITE_FONT_METRICS1 as FontMetrics1;
pub use winapi::um::dwrite_3::DWRITE_FONT_AXIS_VALUE;
use winapi::um::libloaderapi::{GetProcAddress, LoadLibraryW};

#[macro_use]
mod com_helpers;

mod bitmap_render_target;
pub use bitmap_render_target::BitmapRenderTarget;
mod font;
pub use font::{Font, FontMetrics, InformationalStringId};
mod font_collection;
pub use font_collection::FontCollection;
mod font_face;
pub use font_face::{FontFace, FontFaceType};
mod font_fallback;
pub use font_fallback::{FallbackResult, FontFallback};
mod font_family;
pub use font_family::FontFamily;
mod font_file;
pub use font_file::FontFile;
mod gdi_interop;
pub use gdi_interop::GdiInterop;
mod outline_builder;
pub use outline_builder::OutlineBuilder;
mod rendering_params;
pub use rendering_params::RenderingParams;
mod text_analysis_source;
pub use text_analysis_source::TextAnalysisSource;
mod glyph_run_analysis;
pub use glyph_run_analysis::GlyphRunAnalysis;

// This is an internal implementation of FontFileLoader, for our utility
// functions.  We don't wrap the DWriteFontFileLoader interface and
// related things.
mod font_file_loader_impl;

// This is an implementation of `FontCollectionLoader` for client code.
mod font_collection_impl;
pub use font_collection_impl::CustomFontCollectionLoaderImpl;

// This is an implementation of `TextAnalysisSource` for client code.
mod text_analysis_source_impl;
pub use text_analysis_source_impl::{
    CustomTextAnalysisSourceImpl, NumberSubstitution, TextAnalysisSourceMethods,
};

// This is an internal implementation of `GeometrySink` so that we can
// expose `IDWriteGeometrySink` in an idiomatic way.
mod geometry_sink_impl;

lazy_static! {
    static ref DWRITE_FACTORY_RAW_PTR: usize = {
        unsafe {
            type DWriteCreateFactoryType =
                extern "system" fn(DWRITE_FACTORY_TYPE, REFIID, *mut *mut IUnknown) -> HRESULT;

            let dwrite_dll = LoadLibraryW("dwrite.dll".to_wide_null().as_ptr());
            assert!(!dwrite_dll.is_null());
            let create_factory_name = CString::new("DWriteCreateFactory").unwrap();
            let dwrite_create_factory_ptr =
                GetProcAddress(dwrite_dll, create_factory_name.as_ptr() as LPCSTR);
            assert!(!dwrite_create_factory_ptr.is_null());

            let dwrite_create_factory = mem::transmute::<*const c_void, DWriteCreateFactoryType>(
                dwrite_create_factory_ptr as *const _,
            );

            let mut factory: *mut IDWriteFactory = ptr::null_mut();
            let hr = dwrite_create_factory(
                DWRITE_FACTORY_TYPE_SHARED,
                &IDWriteFactory::uuidof(),
                &mut factory as *mut *mut IDWriteFactory as *mut *mut IUnknown,
            );
            assert!(hr == S_OK);
            factory as usize
        }
    };
    static ref DEFAULT_DWRITE_RENDERING_PARAMS_RAW_PTR: usize = {
        unsafe {
            let mut default_rendering_params: *mut IDWriteRenderingParams = ptr::null_mut();
            let hr = (*DWriteFactory()).CreateRenderingParams(&mut default_rendering_params);
            assert!(hr == S_OK);
            default_rendering_params as usize
        }
    };
} // end lazy static

// FIXME vlad would be nice to return, say, FactoryPtr<IDWriteFactory>
// that has a DerefMut impl, so that we can write
// DWriteFactory().SomeOperation() as opposed to
// (*DWriteFactory()).SomeOperation()
#[allow(non_snake_case)]
fn DWriteFactory() -> *mut IDWriteFactory {
    (*DWRITE_FACTORY_RAW_PTR) as *mut IDWriteFactory
}

#[allow(non_snake_case)]
fn DefaultDWriteRenderParams() -> *mut IDWriteRenderingParams {
    (*DEFAULT_DWRITE_RENDERING_PARAMS_RAW_PTR) as *mut IDWriteRenderingParams
}