@@ -16,36 +16,25 @@ use crate::fonts::{self, FaceId};
1616use crate :: { shaper, Glyph , Range , Vec2 } ;
1717
1818/// Effect formatting marker
19- #[ derive( Clone , Debug , PartialEq , Eq ) ]
19+ #[ derive( Clone , Debug , Default , PartialEq , Eq ) ]
2020#[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
21- pub struct Effect < X > {
21+ pub struct Effect {
2222 /// Index in text at which formatting becomes active
2323 ///
2424 /// (Note that we use `u32` not `usize` since it can be assumed text length
2525 /// will never exceed `u32::MAX`.)
2626 pub start : u32 ,
27+ /// User-specified value, e.g. index into a colour palette
28+ pub e : u16 ,
2729 /// Effect flags
2830 pub flags : EffectFlags ,
29- /// User payload
30- pub aux : X ,
31- }
32-
33- impl < X > Effect < X > {
34- /// Construct a "default" instance with the supplied `aux` value
35- pub fn default ( aux : X ) -> Self {
36- Effect {
37- start : 0 ,
38- flags : EffectFlags :: empty ( ) ,
39- aux,
40- }
41- }
4231}
4332
4433bitflags:: bitflags! {
4534 /// Text effects
4635 #[ derive( Clone , Copy , Debug , Default , PartialEq , Eq ) ]
4736 #[ cfg_attr( feature = "serde" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
48- pub struct EffectFlags : u32 {
37+ pub struct EffectFlags : u16 {
4938 /// Glyph is underlined
5039 const UNDERLINE = 1 << 0 ;
5140 /// Glyph is crossed through by a center-line
@@ -143,15 +132,14 @@ impl ExactSizeIterator for MarkerPosIter {}
143132/// A sequence of positioned glyphs with effects
144133///
145134/// Yielded by [`TextDisplay::runs`] and [`TextDisplay::runs_with_effects`].
146- pub struct GlyphRun < ' a , X : Copy > {
135+ pub struct GlyphRun < ' a > {
147136 run : & ' a shaper:: GlyphRun ,
148137 range : Range ,
149138 offset : Vec2 ,
150- effects : & ' a [ Effect < X > ] ,
151- default_aux : X ,
139+ effects : & ' a [ Effect ] ,
152140}
153141
154- impl < ' a , X : Copy > GlyphRun < ' a , X > {
142+ impl < ' a > GlyphRun < ' a > {
155143 /// Get the font face used for this run
156144 #[ inline]
157145 pub fn face_id ( & self ) -> FaceId {
@@ -182,25 +170,22 @@ impl<'a, X: Copy> GlyphRun<'a, X> {
182170
183171 /// Yield glyphs and effects for this run
184172 ///
185- /// The callback `f` receives `glyph, i, aux` where
186- /// `dpu` and `height` are both measures of the font size (pixels per font
187- /// unit and pixels per height, respectively), and `i` is the index within
188- /// `effects` (or `usize::MAX` when a default-constructed effect token is
189- /// used).
173+ /// The callback `f` receives `glyph, e` where `e` is the [`Effect::e`]
174+ /// value (defaults to 0).
190175 ///
191176 /// The callback `g` receives positioning for each underline/strike-through
192177 /// segment: `x1, x2, y_top, h` where `h` is the thickness (height). Note
193178 /// that it is possible to have `h < 1.0` and `y_top, y_top + h` to round to
194179 /// the same number; the renderer is responsible for ensuring such lines
195- /// are actually visible. The last parameters are `i, aux ` as for `f`.
180+ /// are actually visible. The last parameter is `e ` as for `f`.
196181 ///
197182 /// Note: this is more computationally expensive than [`GlyphRun::glyphs`],
198183 /// so you may prefer to call that. Optionally one may choose to cache the
199184 /// result, though this is not really necessary.
200185 pub fn glyphs_with_effects < F , G > ( & self , mut f : F , mut g : G )
201186 where
202- F : FnMut ( Glyph , usize , X ) ,
203- G : FnMut ( f32 , f32 , f32 , f32 , usize , X ) ,
187+ F : FnMut ( Glyph , u16 ) ,
188+ G : FnMut ( f32 , f32 , f32 , f32 , u16 ) ,
204189 {
205190 let sf = fonts:: library ( )
206191 . get_face ( self . run . face_id )
@@ -237,9 +222,7 @@ impl<'a, X: Copy> GlyphRun<'a, X> {
237222 . effects
238223 . get ( effect_cur)
239224 . cloned ( )
240- . unwrap_or ( Effect :: default ( self . default_aux ) ) ;
241-
242- let mut effect_i = effect_cur;
225+ . unwrap_or ( Effect :: default ( ) ) ;
243226
244227 // In case an effect applies to the left-most glyph, it starts from that
245228 // glyph's x coordinate.
@@ -251,15 +234,15 @@ impl<'a, X: Copy> GlyphRun<'a, X> {
251234 let y_top = position. 1 - metrics. position ;
252235 let h = metrics. thickness ;
253236 let x1 = position. 0 ;
254- underline = Some ( ( x1, y_top, h, fmt. aux ) ) ;
237+ underline = Some ( ( x1, y_top, h, fmt. e ) ) ;
255238 }
256239 }
257240 if fmt. flags . contains ( EffectFlags :: STRIKETHROUGH ) {
258241 if let Some ( metrics) = sf. strikethrough_metrics ( ) {
259242 let y_top = position. 1 - metrics. position ;
260243 let h = metrics. thickness ;
261244 let x1 = position. 0 ;
262- strikethrough = Some ( ( x1, y_top, h, fmt. aux ) ) ;
245+ strikethrough = Some ( ( x1, y_top, h, fmt. e ) ) ;
263246 }
264247 }
265248 }
@@ -303,55 +286,53 @@ impl<'a, X: Copy> GlyphRun<'a, X> {
303286 . effects
304287 . get ( effect_cur)
305288 . cloned ( )
306- . unwrap_or ( Effect :: default ( self . default_aux ) ) ;
289+ . unwrap_or ( Effect :: default ( ) ) ;
307290
308291 if underline. is_some ( ) != fmt. flags . contains ( EffectFlags :: UNDERLINE ) {
309- if let Some ( ( x1, y_top, h, aux ) ) = underline {
292+ if let Some ( ( x1, y_top, h, e ) ) = underline {
310293 let x2 = glyph. position . 0 ;
311- g ( x1, x2, y_top, h, effect_i , aux ) ;
294+ g ( x1, x2, y_top, h, e ) ;
312295 underline = None ;
313296 } else if let Some ( metrics) = sf. underline_metrics ( ) {
314297 let y_top = glyph. position . 1 - metrics. position ;
315298 let h = metrics. thickness ;
316299 let x1 = glyph. position . 0 ;
317- underline = Some ( ( x1, y_top, h, fmt. aux ) ) ;
300+ underline = Some ( ( x1, y_top, h, fmt. e ) ) ;
318301 }
319302 }
320303 if strikethrough. is_some ( ) != fmt. flags . contains ( EffectFlags :: STRIKETHROUGH ) {
321- if let Some ( ( x1, y_top, h, aux ) ) = strikethrough {
304+ if let Some ( ( x1, y_top, h, e ) ) = strikethrough {
322305 let x2 = glyph. position . 0 ;
323- g ( x1, x2, y_top, h, effect_i , aux ) ;
306+ g ( x1, x2, y_top, h, e ) ;
324307 strikethrough = None ;
325308 } else if let Some ( metrics) = sf. strikethrough_metrics ( ) {
326309 let y_top = glyph. position . 1 - metrics. position ;
327310 let h = metrics. thickness ;
328311 let x1 = glyph. position . 0 ;
329- strikethrough = Some ( ( x1, y_top, h, fmt. aux ) ) ;
312+ strikethrough = Some ( ( x1, y_top, h, fmt. e ) ) ;
330313 }
331314 }
332-
333- effect_i = effect_cur;
334315 }
335316
336- f ( glyph, effect_cur , fmt. aux ) ;
317+ f ( glyph, fmt. e ) ;
337318 }
338319
339320 // Effects end at the following glyph's start (or end of this run part)
340- if let Some ( ( x1, y_top, h, aux ) ) = underline {
321+ if let Some ( ( x1, y_top, h, e ) ) = underline {
341322 let x2 = if self . range . end ( ) < self . run . glyphs . len ( ) {
342323 self . run . glyphs [ self . range . end ( ) ] . position . 0
343324 } else {
344325 self . run . caret
345326 } + self . offset . 0 ;
346- g ( x1, x2, y_top, h, effect_i , aux ) ;
327+ g ( x1, x2, y_top, h, e ) ;
347328 }
348- if let Some ( ( x1, y_top, h, aux ) ) = strikethrough {
329+ if let Some ( ( x1, y_top, h, e ) ) = strikethrough {
349330 let x2 = if self . range . end ( ) < self . run . glyphs . len ( ) {
350331 self . run . glyphs [ self . range . end ( ) ] . position . 0
351332 } else {
352333 self . run . caret
353334 } + self . offset . 0 ;
354- g ( x1, x2, y_top, h, effect_i , aux ) ;
335+ g ( x1, x2, y_top, h, e ) ;
355336 }
356337 }
357338}
@@ -461,43 +442,31 @@ impl TextDisplay {
461442
462443 /// Iterate over runs of positioned glyphs
463444 ///
464- /// This method is just sugar for `self.runs_with_effects(&[], ())`.
445+ /// All glyphs are translated by the given `offset` (this is practically
446+ /// free).
465447 ///
466- /// [Requires status][Self#status-of-preparation]:
467- /// text is fully prepared for display.
448+ /// An [`Effect`] sequence supports underline, strikethrough and custom
449+ /// indexing (e.g. for a color palette). Pass `&[]` if effects are not
450+ /// required. (The default effect is always [`Effect::default()`].)
468451 ///
469452 /// Runs are yielded in undefined order. The total number of
470453 /// glyphs yielded will equal [`TextDisplay::num_glyphs`].
471- pub fn runs ( & self ) -> impl Iterator < Item = GlyphRun < ' _ , ( ) > > {
472- self . runs_with_effects ( & [ ] , ( ) )
473- }
474-
475- /// Iterate over runs of positioned glyphs with effects
476- ///
477- /// If the list `effects` is empty or has first entry with `start > 0`, the
478- /// result of `Effect::default(default_aux)` is used. The user payload of
479- /// type `X` is simply passed through to `f` and `g` calls and may be useful
480- /// for color information.
481454 ///
482455 /// [Requires status][Self#status-of-preparation]:
483456 /// text is fully prepared for display.
484- ///
485- /// Runs are yielded in undefined order. The total number of
486- /// glyphs yielded will equal [`TextDisplay::num_glyphs`].
487- pub fn runs_with_effects < ' a , X : Copy > (
457+ pub fn runs < ' a > (
488458 & ' a self ,
489- effects : & ' a [ Effect < X > ] ,
490- default_aux : X ,
491- ) -> impl Iterator < Item = GlyphRun < ' a , X > > + ' a {
459+ offset : Vec2 ,
460+ effects : & ' a [ Effect ] ,
461+ ) -> impl Iterator < Item = GlyphRun < ' a > > + ' a {
492462 self . wrapped_runs
493463 . iter ( )
494464 . filter ( |part| !part. glyph_range . is_empty ( ) )
495465 . map ( move |part| GlyphRun {
496466 run : & self . runs [ to_usize ( part. glyph_run ) ] ,
497467 range : part. glyph_range ,
498- offset : part. offset ,
468+ offset : offset + part. offset ,
499469 effects,
500- default_aux,
501470 } )
502471 }
503472
0 commit comments