4
4
5
5
use std:: cell:: UnsafeCell ;
6
6
use std:: mem:: { self , zeroed} ;
7
- use std:: ptr;
8
7
use std:: slice;
8
+ use std:: { error, fmt, ptr} ;
9
9
use winapi:: ctypes:: c_void;
10
10
use winapi:: shared:: minwindef:: { BOOL , FALSE , TRUE } ;
11
11
use winapi:: shared:: winerror:: S_OK ;
@@ -21,6 +21,7 @@ use winapi::um::dwrite::{DWRITE_GLYPH_OFFSET, DWRITE_MATRIX, DWRITE_RENDERING_MO
21
21
use winapi:: um:: dwrite:: { DWRITE_RENDERING_MODE_DEFAULT , DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC } ;
22
22
use winapi:: um:: dwrite_1:: IDWriteFontFace1 ;
23
23
use winapi:: um:: dwrite_3:: { IDWriteFontFace5 , IDWriteFontResource , DWRITE_FONT_AXIS_VALUE } ;
24
+ use winapi:: um:: winnt:: HRESULT ;
24
25
use winapi:: Interface ;
25
26
use wio:: com:: ComPtr ;
26
27
@@ -49,25 +50,35 @@ impl FontFace {
49
50
( * self . native . get ( ) ) . as_raw ( )
50
51
}
51
52
52
- unsafe fn get_raw_files ( & self ) -> Vec < * mut IDWriteFontFile > {
53
+ unsafe fn raw_files ( & self ) -> Result < Vec < * mut IDWriteFontFile > , HRESULT > {
53
54
let mut number_of_files: u32 = 0 ;
54
55
let hr = ( * self . native . get ( ) ) . GetFiles ( & mut number_of_files, ptr:: null_mut ( ) ) ;
55
- assert ! ( hr == 0 ) ;
56
+ if hr != S_OK {
57
+ return Err ( hr) ;
58
+ }
56
59
57
60
let mut file_ptrs: Vec < * mut IDWriteFontFile > =
58
61
vec ! [ ptr:: null_mut( ) ; number_of_files as usize ] ;
59
62
let hr = ( * self . native . get ( ) ) . GetFiles ( & mut number_of_files, file_ptrs. as_mut_ptr ( ) ) ;
60
- assert ! ( hr == 0 ) ;
61
- file_ptrs
63
+ if hr != S_OK {
64
+ return Err ( hr) ;
65
+ }
66
+ Ok ( file_ptrs)
62
67
}
63
68
69
+ #[ deprecated( note = "Use `files` instead." ) ]
64
70
pub fn get_files ( & self ) -> Vec < FontFile > {
71
+ self . files ( ) . unwrap ( )
72
+ }
73
+
74
+ pub fn files ( & self ) -> Result < Vec < FontFile > , HRESULT > {
65
75
unsafe {
66
- let file_ptrs = self . get_raw_files ( ) ;
67
- file_ptrs
68
- . iter ( )
69
- . map ( |p| FontFile :: take ( ComPtr :: from_raw ( * p) ) )
70
- . collect ( )
76
+ self . raw_files ( ) . map ( |file_ptrs| {
77
+ file_ptrs
78
+ . iter ( )
79
+ . map ( |p| FontFile :: take ( ComPtr :: from_raw ( * p) ) )
80
+ . collect ( )
81
+ } )
71
82
}
72
83
}
73
84
@@ -76,7 +87,7 @@ impl FontFace {
76
87
simulations : DWRITE_FONT_SIMULATIONS ,
77
88
) -> FontFace {
78
89
unsafe {
79
- let file_ptrs = self . get_raw_files ( ) ;
90
+ let file_ptrs = self . raw_files ( ) . unwrap ( ) ;
80
91
let face_type = ( * self . native . get ( ) ) . GetType ( ) ;
81
92
let face_index = ( * self . native . get ( ) ) . GetIndex ( ) ;
82
93
let mut face: * mut IDWriteFontFace = ptr:: null_mut ( ) ;
@@ -118,24 +129,41 @@ impl FontFace {
118
129
}
119
130
}
120
131
132
+ #[ deprecated( note = "Use `glyph_indices` instead." ) ]
121
133
pub fn get_glyph_indices ( & self , code_points : & [ u32 ] ) -> Vec < u16 > {
134
+ self . glyph_indices ( code_points) . unwrap ( )
135
+ }
136
+
137
+ pub fn glyph_indices ( & self , code_points : & [ u32 ] ) -> Result < Vec < u16 > , HRESULT > {
138
+ let mut glyph_indices: Vec < u16 > = vec ! [ 0 ; code_points. len( ) ] ;
122
139
unsafe {
123
- let mut glyph_indices: Vec < u16 > = vec ! [ 0 ; code_points. len( ) ] ;
124
140
let hr = ( * self . native . get ( ) ) . GetGlyphIndices (
125
141
code_points. as_ptr ( ) ,
126
142
code_points. len ( ) as u32 ,
127
143
glyph_indices. as_mut_ptr ( ) ,
128
144
) ;
129
- assert ! ( hr == 0 ) ;
130
- glyph_indices
145
+ if hr != S_OK {
146
+ return Err ( hr) ;
147
+ }
148
+ Ok ( glyph_indices)
131
149
}
132
150
}
133
151
152
+ #[ deprecated( note = "Use `design_glyph_metrics` instead." ) ]
134
153
pub fn get_design_glyph_metrics (
135
154
& self ,
136
155
glyph_indices : & [ u16 ] ,
137
156
is_sideways : bool ,
138
157
) -> Vec < DWRITE_GLYPH_METRICS > {
158
+ self . design_glyph_metrics ( glyph_indices, is_sideways)
159
+ . unwrap ( )
160
+ }
161
+
162
+ pub fn design_glyph_metrics (
163
+ & self ,
164
+ glyph_indices : & [ u16 ] ,
165
+ is_sideways : bool ,
166
+ ) -> Result < Vec < DWRITE_GLYPH_METRICS > , HRESULT > {
139
167
unsafe {
140
168
let mut metrics: Vec < DWRITE_GLYPH_METRICS > = vec ! [ zeroed( ) ; glyph_indices. len( ) ] ;
141
169
let hr = ( * self . native . get ( ) ) . GetDesignGlyphMetrics (
@@ -144,11 +172,14 @@ impl FontFace {
144
172
metrics. as_mut_ptr ( ) ,
145
173
is_sideways as BOOL ,
146
174
) ;
147
- assert ! ( hr == 0 ) ;
148
- metrics
175
+ if hr != S_OK {
176
+ return Err ( hr) ;
177
+ }
178
+ Ok ( metrics)
149
179
}
150
180
}
151
181
182
+ #[ deprecated( note = "Use `gdi_compatible_glyph_metrics` instead." ) ]
152
183
pub fn get_gdi_compatible_glyph_metrics (
153
184
& self ,
154
185
em_size : f32 ,
@@ -158,6 +189,26 @@ impl FontFace {
158
189
glyph_indices : & [ u16 ] ,
159
190
is_sideways : bool ,
160
191
) -> Vec < DWRITE_GLYPH_METRICS > {
192
+ self . gdi_compatible_glyph_metrics (
193
+ em_size,
194
+ pixels_per_dip,
195
+ transform,
196
+ use_gdi_natural,
197
+ glyph_indices,
198
+ is_sideways,
199
+ )
200
+ . unwrap ( )
201
+ }
202
+
203
+ pub fn gdi_compatible_glyph_metrics (
204
+ & self ,
205
+ em_size : f32 ,
206
+ pixels_per_dip : f32 ,
207
+ transform : * const DWRITE_MATRIX ,
208
+ use_gdi_natural : bool ,
209
+ glyph_indices : & [ u16 ] ,
210
+ is_sideways : bool ,
211
+ ) -> Result < Vec < DWRITE_GLYPH_METRICS > , HRESULT > {
161
212
unsafe {
162
213
let mut metrics: Vec < DWRITE_GLYPH_METRICS > = vec ! [ zeroed( ) ; glyph_indices. len( ) ] ;
163
214
let hr = ( * self . native . get ( ) ) . GetGdiCompatibleGlyphMetrics (
@@ -170,40 +221,48 @@ impl FontFace {
170
221
metrics. as_mut_ptr ( ) ,
171
222
is_sideways as BOOL ,
172
223
) ;
173
- assert ! ( hr == 0 ) ;
174
- metrics
224
+ if hr != S_OK {
225
+ return Err ( hr) ;
226
+ }
227
+ Ok ( metrics)
175
228
}
176
229
}
177
230
231
+ #[ deprecated( note = "Use `font_table` instead." ) ]
232
+ pub fn get_font_table ( & self , opentype_table_tag : u32 ) -> Option < Vec < u8 > > {
233
+ self . font_table ( opentype_table_tag) . unwrap ( )
234
+ }
235
+
178
236
/// Returns the contents of the OpenType table with the given tag.
179
237
///
180
238
/// NB: The bytes of the tag are reversed! You probably want to use the `u32::swap_bytes()`
181
239
/// method on the tag value before calling this method.
182
- pub fn get_font_table ( & self , opentype_table_tag : u32 ) -> Option < Vec < u8 > > {
240
+ pub fn font_table ( & self , opentype_table_tag : u32 ) -> Result < Option < Vec < u8 > > , HRESULT > {
241
+ let mut table_data_ptr: * const u8 = ptr:: null_mut ( ) ;
242
+ let mut table_size: u32 = 0 ;
243
+ let mut table_context: * mut c_void = ptr:: null_mut ( ) ;
244
+ let mut exists: BOOL = FALSE ;
183
245
unsafe {
184
- let mut table_data_ptr: * const u8 = ptr:: null_mut ( ) ;
185
- let mut table_size: u32 = 0 ;
186
- let mut table_context: * mut c_void = ptr:: null_mut ( ) ;
187
- let mut exists: BOOL = FALSE ;
188
-
189
246
let hr = ( * self . native . get ( ) ) . TryGetFontTable (
190
247
opentype_table_tag,
191
248
& mut table_data_ptr as * mut * const _ as * mut * const c_void ,
192
249
& mut table_size,
193
250
& mut table_context,
194
251
& mut exists,
195
252
) ;
196
- assert ! ( hr == 0 ) ;
253
+ if hr != S_OK {
254
+ return Err ( hr) ;
255
+ }
197
256
198
257
if exists == FALSE {
199
- return None ;
258
+ return Ok ( None ) ;
200
259
}
201
260
202
261
let table_bytes = slice:: from_raw_parts ( table_data_ptr, table_size as usize ) . to_vec ( ) ;
203
262
204
263
( * self . native . get ( ) ) . ReleaseFontTable ( table_context) ;
205
264
206
- Some ( table_bytes)
265
+ Ok ( Some ( table_bytes) )
207
266
}
208
267
}
209
268
@@ -224,7 +283,7 @@ impl FontFace {
224
283
& mut render_mode,
225
284
) ;
226
285
227
- if hr != 0 {
286
+ if hr != S_OK {
228
287
return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC ;
229
288
}
230
289
@@ -246,6 +305,7 @@ impl FontFace {
246
305
)
247
306
}
248
307
308
+ #[ deprecated( note = "Use `glyph_run_outline` instead." ) ]
249
309
pub fn get_glyph_run_outline (
250
310
& self ,
251
311
em_size : f32 ,
@@ -256,25 +316,51 @@ impl FontFace {
256
316
is_right_to_left : bool ,
257
317
outline_builder : Box < dyn OutlineBuilder > ,
258
318
) {
259
- unsafe {
260
- let glyph_advances = match glyph_advances {
261
- None => ptr:: null ( ) ,
262
- Some ( glyph_advances) => {
263
- assert_eq ! ( glyph_advances. len( ) , glyph_indices. len( ) ) ;
264
- glyph_advances. as_ptr ( )
319
+ self . glyph_run_outline (
320
+ em_size,
321
+ glyph_indices,
322
+ glyph_advances,
323
+ glyph_offsets,
324
+ is_sideways,
325
+ is_right_to_left,
326
+ outline_builder,
327
+ )
328
+ . unwrap ( )
329
+ }
330
+
331
+ pub fn glyph_run_outline (
332
+ & self ,
333
+ em_size : f32 ,
334
+ glyph_indices : & [ u16 ] ,
335
+ glyph_advances : Option < & [ f32 ] > ,
336
+ glyph_offsets : Option < & [ DWRITE_GLYPH_OFFSET ] > ,
337
+ is_sideways : bool ,
338
+ is_right_to_left : bool ,
339
+ outline_builder : Box < dyn OutlineBuilder > ,
340
+ ) -> Result < ( ) , GlyphRunOutlineError > {
341
+ let glyph_advances = match glyph_advances {
342
+ None => ptr:: null ( ) ,
343
+ Some ( glyph_advances) => {
344
+ if glyph_advances. len ( ) != glyph_indices. len ( ) {
345
+ return Err ( GlyphRunOutlineError :: InvalidInput ) ;
265
346
}
266
- } ;
267
- let glyph_offsets = match glyph_offsets {
268
- None => ptr:: null ( ) ,
269
- Some ( glyph_offsets) => {
270
- assert_eq ! ( glyph_offsets. len( ) , glyph_indices. len( ) ) ;
271
- glyph_offsets. as_ptr ( )
347
+ glyph_advances. as_ptr ( )
348
+ }
349
+ } ;
350
+ let glyph_offsets = match glyph_offsets {
351
+ None => ptr:: null ( ) ,
352
+ Some ( glyph_offsets) => {
353
+ if glyph_offsets. len ( ) != glyph_indices. len ( ) {
354
+ return Err ( GlyphRunOutlineError :: InvalidInput ) ;
272
355
}
273
- } ;
274
- let is_sideways = if is_sideways { TRUE } else { FALSE } ;
275
- let is_right_to_left = if is_right_to_left { TRUE } else { FALSE } ;
276
- let geometry_sink = GeometrySinkImpl :: new ( outline_builder) ;
277
- let geometry_sink = geometry_sink. into_interface ( ) ;
356
+ glyph_offsets. as_ptr ( )
357
+ }
358
+ } ;
359
+ let is_sideways = if is_sideways { TRUE } else { FALSE } ;
360
+ let is_right_to_left = if is_right_to_left { TRUE } else { FALSE } ;
361
+ let geometry_sink = GeometrySinkImpl :: new ( outline_builder) ;
362
+ let geometry_sink = geometry_sink. into_interface ( ) ;
363
+ unsafe {
278
364
let hr = ( * self . native . get ( ) ) . GetGlyphRunOutline (
279
365
em_size,
280
366
glyph_indices. as_ptr ( ) ,
@@ -285,8 +371,11 @@ impl FontFace {
285
371
is_right_to_left,
286
372
geometry_sink,
287
373
) ;
288
- assert_eq ! ( hr, S_OK ) ;
374
+ if hr != S_OK {
375
+ return Err ( GlyphRunOutlineError :: Win32Error ( hr) ) ;
376
+ }
289
377
}
378
+ Ok ( ( ) )
290
379
}
291
380
292
381
pub fn has_kerning_pairs ( & self ) -> bool {
@@ -298,7 +387,17 @@ impl FontFace {
298
387
}
299
388
}
300
389
390
+ #[ deprecated( note = "Use `glyph_pair_kerning_adjustment` instead." ) ]
301
391
pub fn get_glyph_pair_kerning_adjustment ( & self , first_glyph : u16 , second_glyph : u16 ) -> i32 {
392
+ self . glyph_pair_kerning_adjustment ( first_glyph, second_glyph)
393
+ . unwrap ( )
394
+ }
395
+
396
+ pub fn glyph_pair_kerning_adjustment (
397
+ & self ,
398
+ first_glyph : u16 ,
399
+ second_glyph : u16 ,
400
+ ) -> Result < i32 , HRESULT > {
302
401
unsafe {
303
402
match self . get_face1 ( ) {
304
403
Some ( face1) => {
@@ -308,11 +407,13 @@ impl FontFace {
308
407
[ first_glyph, second_glyph] . as_ptr ( ) ,
309
408
adjustments. as_mut_ptr ( ) ,
310
409
) ;
311
- assert_eq ! ( hr, S_OK ) ;
410
+ if hr != S_OK {
411
+ return Err ( hr) ;
412
+ }
312
413
313
- adjustments[ 0 ]
414
+ Ok ( adjustments[ 0 ] )
314
415
}
315
- None => 0 ,
416
+ None => Ok ( 0 ) ,
316
417
}
317
418
}
318
419
}
@@ -420,3 +521,20 @@ pub enum FontFaceType {
420
521
Vector ,
421
522
Bitmap ,
422
523
}
524
+
525
+ #[ derive( Debug ) ]
526
+ pub enum GlyphRunOutlineError {
527
+ InvalidInput ,
528
+ Win32Error ( HRESULT ) ,
529
+ }
530
+
531
+ impl fmt:: Display for GlyphRunOutlineError {
532
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
533
+ match self {
534
+ Self :: InvalidInput => write ! ( f, "Invalid input" ) ,
535
+ Self :: Win32Error ( code) => write ! ( f, "{:#x}" , code) ,
536
+ }
537
+ }
538
+ }
539
+
540
+ impl error:: Error for GlyphRunOutlineError { }
0 commit comments