@@ -231,6 +231,34 @@ impl LrmScale {
231
231
} )
232
232
}
233
233
234
+ /// Returns a measure given a distance along the `LrmScale`.
235
+ /// The corresponding [Anchor] is the named `Anchor` that gives the smallest positive `offset`.
236
+ /// If such an `Anchor` does not exists, the first named `Anchor` is used.
237
+ pub fn get_measure (
238
+ & self ,
239
+ scale_position : ScalePosition ,
240
+ ) -> Result < LrmScaleMeasure , LrmScaleError > {
241
+ let named_anchor = self
242
+ . scale_nearest_named ( scale_position)
243
+ . ok_or ( LrmScaleError :: NoAnchorFound ) ?;
244
+
245
+ Ok ( LrmScaleMeasure {
246
+ anchor_name : named_anchor. id ,
247
+ scale_offset : scale_position - named_anchor. scale_position ,
248
+ } )
249
+ }
250
+
251
+ /// Locates a point along the scale given an [Anchor] and an `offset`,
252
+ /// which might be negative.
253
+ pub fn get_position ( & self , measure : LrmScaleMeasure ) -> Result < ScalePosition , LrmScaleError > {
254
+ let named_anchor = self
255
+ . iter_named ( )
256
+ . find ( |anchor| anchor. id == measure. anchor_name )
257
+ . ok_or ( LrmScaleError :: UnknownAnchorName ) ?;
258
+
259
+ Ok ( named_anchor. scale_position + measure. scale_offset )
260
+ }
261
+
234
262
fn nearest_named ( & self , curve_position : CurvePosition ) -> Option < NamedAnchor > {
235
263
// Tries to find the Anchor whose curve_position is the biggest possible, yet smaller than Curve position
236
264
// Otherwise take the first named
@@ -246,6 +274,14 @@ impl LrmScale {
246
274
. or_else ( || self . iter_named ( ) . next ( ) )
247
275
}
248
276
277
+ fn scale_nearest_named ( & self , scale_position : ScalePosition ) -> Option < NamedAnchor > {
278
+ // Like nearest_named, but our position is along the scale
279
+ self . iter_named ( )
280
+ . rev ( )
281
+ . find ( |anchor| anchor. scale_position <= scale_position)
282
+ . or_else ( || self . iter_named ( ) . next ( ) )
283
+ }
284
+
249
285
// Finds the closest Anchor before the Anchor having the name `name`
250
286
fn previous_anchor ( & self , name : & str ) -> Option < & Anchor > {
251
287
self . anchors
@@ -383,4 +419,34 @@ mod tests {
383
419
assert_eq ! ( measure. anchor_name, "b" ) ;
384
420
assert_eq ! ( measure. scale_offset, 2. ) ;
385
421
}
422
+
423
+ #[ test]
424
+ fn get_measure ( ) {
425
+ let measure = scale ( ) . get_measure ( 5. ) . unwrap ( ) ;
426
+ assert_eq ! ( measure. anchor_name, "a" ) ;
427
+ assert_eq ! ( measure. scale_offset, 5. ) ;
428
+
429
+ let measure = scale ( ) . get_measure ( 25. ) . unwrap ( ) ;
430
+ assert_eq ! ( measure. anchor_name, "b" ) ;
431
+ assert_eq ! ( measure. scale_offset, 15. ) ;
432
+ }
433
+
434
+ #[ test]
435
+ fn get_position ( ) {
436
+ let position = scale ( )
437
+ . get_position ( LrmScaleMeasure {
438
+ anchor_name : "a" . to_string ( ) ,
439
+ scale_offset : 5. ,
440
+ } )
441
+ . unwrap ( ) ;
442
+ assert_eq ! ( position, 5. ) ;
443
+
444
+ let position = scale ( )
445
+ . get_position ( LrmScaleMeasure {
446
+ anchor_name : "b" . to_string ( ) ,
447
+ scale_offset : 15. ,
448
+ } )
449
+ . unwrap ( ) ;
450
+ assert_eq ! ( position, 25. ) ;
451
+ }
386
452
}
0 commit comments