44
55use std:: cell:: UnsafeCell ;
66use std:: mem:: { self , zeroed} ;
7- use std:: ptr;
87use std:: slice;
8+ use std:: { error, fmt, ptr} ;
99use winapi:: ctypes:: c_void;
1010use winapi:: shared:: minwindef:: { BOOL , FALSE , TRUE } ;
1111use winapi:: shared:: winerror:: S_OK ;
@@ -21,6 +21,7 @@ use winapi::um::dwrite::{DWRITE_GLYPH_OFFSET, DWRITE_MATRIX, DWRITE_RENDERING_MO
2121use winapi:: um:: dwrite:: { DWRITE_RENDERING_MODE_DEFAULT , DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC } ;
2222use winapi:: um:: dwrite_1:: IDWriteFontFace1 ;
2323use winapi:: um:: dwrite_3:: { IDWriteFontFace5 , IDWriteFontResource , DWRITE_FONT_AXIS_VALUE } ;
24+ use winapi:: um:: winnt:: HRESULT ;
2425use winapi:: Interface ;
2526use wio:: com:: ComPtr ;
2627
@@ -49,25 +50,35 @@ impl FontFace {
4950 ( * self . native . get ( ) ) . as_raw ( )
5051 }
5152
52- unsafe fn get_raw_files ( & self ) -> Vec < * mut IDWriteFontFile > {
53+ unsafe fn raw_files ( & self ) -> Result < Vec < * mut IDWriteFontFile > , HRESULT > {
5354 let mut number_of_files: u32 = 0 ;
5455 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+ }
5659
5760 let mut file_ptrs: Vec < * mut IDWriteFontFile > =
5861 vec ! [ ptr:: null_mut( ) ; number_of_files as usize ] ;
5962 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)
6267 }
6368
69+ #[ deprecated( note = "Use `files` instead." ) ]
6470 pub fn get_files ( & self ) -> Vec < FontFile > {
71+ self . files ( ) . unwrap ( )
72+ }
73+
74+ pub fn files ( & self ) -> Result < Vec < FontFile > , HRESULT > {
6575 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+ } )
7182 }
7283 }
7384
@@ -76,7 +87,7 @@ impl FontFace {
7687 simulations : DWRITE_FONT_SIMULATIONS ,
7788 ) -> FontFace {
7889 unsafe {
79- let file_ptrs = self . get_raw_files ( ) ;
90+ let file_ptrs = self . raw_files ( ) . unwrap ( ) ;
8091 let face_type = ( * self . native . get ( ) ) . GetType ( ) ;
8192 let face_index = ( * self . native . get ( ) ) . GetIndex ( ) ;
8293 let mut face: * mut IDWriteFontFace = ptr:: null_mut ( ) ;
@@ -118,24 +129,41 @@ impl FontFace {
118129 }
119130 }
120131
132+ #[ deprecated( note = "Use `glyph_indices` instead." ) ]
121133 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( ) ] ;
122139 unsafe {
123- let mut glyph_indices: Vec < u16 > = vec ! [ 0 ; code_points. len( ) ] ;
124140 let hr = ( * self . native . get ( ) ) . GetGlyphIndices (
125141 code_points. as_ptr ( ) ,
126142 code_points. len ( ) as u32 ,
127143 glyph_indices. as_mut_ptr ( ) ,
128144 ) ;
129- assert ! ( hr == 0 ) ;
130- glyph_indices
145+ if hr != S_OK {
146+ return Err ( hr) ;
147+ }
148+ Ok ( glyph_indices)
131149 }
132150 }
133151
152+ #[ deprecated( note = "Use `design_glyph_metrics` instead." ) ]
134153 pub fn get_design_glyph_metrics (
135154 & self ,
136155 glyph_indices : & [ u16 ] ,
137156 is_sideways : bool ,
138157 ) -> 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 > {
139167 unsafe {
140168 let mut metrics: Vec < DWRITE_GLYPH_METRICS > = vec ! [ zeroed( ) ; glyph_indices. len( ) ] ;
141169 let hr = ( * self . native . get ( ) ) . GetDesignGlyphMetrics (
@@ -144,11 +172,14 @@ impl FontFace {
144172 metrics. as_mut_ptr ( ) ,
145173 is_sideways as BOOL ,
146174 ) ;
147- assert ! ( hr == 0 ) ;
148- metrics
175+ if hr != S_OK {
176+ return Err ( hr) ;
177+ }
178+ Ok ( metrics)
149179 }
150180 }
151181
182+ #[ deprecated( note = "Use `gdi_compatible_glyph_metrics` instead." ) ]
152183 pub fn get_gdi_compatible_glyph_metrics (
153184 & self ,
154185 em_size : f32 ,
@@ -158,6 +189,26 @@ impl FontFace {
158189 glyph_indices : & [ u16 ] ,
159190 is_sideways : bool ,
160191 ) -> 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 > {
161212 unsafe {
162213 let mut metrics: Vec < DWRITE_GLYPH_METRICS > = vec ! [ zeroed( ) ; glyph_indices. len( ) ] ;
163214 let hr = ( * self . native . get ( ) ) . GetGdiCompatibleGlyphMetrics (
@@ -170,40 +221,48 @@ impl FontFace {
170221 metrics. as_mut_ptr ( ) ,
171222 is_sideways as BOOL ,
172223 ) ;
173- assert ! ( hr == 0 ) ;
174- metrics
224+ if hr != S_OK {
225+ return Err ( hr) ;
226+ }
227+ Ok ( metrics)
175228 }
176229 }
177230
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+
178236 /// Returns the contents of the OpenType table with the given tag.
179237 ///
180238 /// NB: The bytes of the tag are reversed! You probably want to use the `u32::swap_bytes()`
181239 /// 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 ;
183245 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-
189246 let hr = ( * self . native . get ( ) ) . TryGetFontTable (
190247 opentype_table_tag,
191248 & mut table_data_ptr as * mut * const _ as * mut * const c_void ,
192249 & mut table_size,
193250 & mut table_context,
194251 & mut exists,
195252 ) ;
196- assert ! ( hr == 0 ) ;
253+ if hr != S_OK {
254+ return Err ( hr) ;
255+ }
197256
198257 if exists == FALSE {
199- return None ;
258+ return Ok ( None ) ;
200259 }
201260
202261 let table_bytes = slice:: from_raw_parts ( table_data_ptr, table_size as usize ) . to_vec ( ) ;
203262
204263 ( * self . native . get ( ) ) . ReleaseFontTable ( table_context) ;
205264
206- Some ( table_bytes)
265+ Ok ( Some ( table_bytes) )
207266 }
208267 }
209268
@@ -224,7 +283,7 @@ impl FontFace {
224283 & mut render_mode,
225284 ) ;
226285
227- if hr != 0 {
286+ if hr != S_OK {
228287 return DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC ;
229288 }
230289
@@ -246,6 +305,7 @@ impl FontFace {
246305 )
247306 }
248307
308+ #[ deprecated( note = "Use `glyph_run_outline` instead." ) ]
249309 pub fn get_glyph_run_outline (
250310 & self ,
251311 em_size : f32 ,
@@ -256,25 +316,51 @@ impl FontFace {
256316 is_right_to_left : bool ,
257317 outline_builder : Box < dyn OutlineBuilder > ,
258318 ) {
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 ) ;
265346 }
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 ) ;
272355 }
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 {
278364 let hr = ( * self . native . get ( ) ) . GetGlyphRunOutline (
279365 em_size,
280366 glyph_indices. as_ptr ( ) ,
@@ -285,8 +371,11 @@ impl FontFace {
285371 is_right_to_left,
286372 geometry_sink,
287373 ) ;
288- assert_eq ! ( hr, S_OK ) ;
374+ if hr != S_OK {
375+ return Err ( GlyphRunOutlineError :: Win32Error ( hr) ) ;
376+ }
289377 }
378+ Ok ( ( ) )
290379 }
291380
292381 pub fn has_kerning_pairs ( & self ) -> bool {
@@ -298,7 +387,17 @@ impl FontFace {
298387 }
299388 }
300389
390+ #[ deprecated( note = "Use `glyph_pair_kerning_adjustment` instead." ) ]
301391 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 > {
302401 unsafe {
303402 match self . get_face1 ( ) {
304403 Some ( face1) => {
@@ -308,11 +407,13 @@ impl FontFace {
308407 [ first_glyph, second_glyph] . as_ptr ( ) ,
309408 adjustments. as_mut_ptr ( ) ,
310409 ) ;
311- assert_eq ! ( hr, S_OK ) ;
410+ if hr != S_OK {
411+ return Err ( hr) ;
412+ }
312413
313- adjustments[ 0 ]
414+ Ok ( adjustments[ 0 ] )
314415 }
315- None => 0 ,
416+ None => Ok ( 0 ) ,
316417 }
317418 }
318419 }
@@ -420,3 +521,20 @@ pub enum FontFaceType {
420521 Vector ,
421522 Bitmap ,
422523}
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