1
1
// Copyright 2021 the Parley Authors
2
2
// SPDX-License-Identifier: Apache-2.0 OR MIT
3
3
4
- use super :: { BreakReason , Brush , Cluster , ClusterInfo , Glyph , Layout , Line , Range , Run , Style } ;
4
+ use super :: {
5
+ BreakReason , Brush , Cluster , ClusterInfo , Glyph , Layout , Line , LineItem , Range , Run , Style ,
6
+ } ;
5
7
use swash:: text:: cluster:: Whitespace ;
6
8
7
9
/// Defines the visual side of the cluster for hit testing.
@@ -21,8 +23,8 @@ impl<'a, B: Brush> Cluster<'a, B> {
21
23
let mut path = ClusterPath :: default ( ) ;
22
24
if let Some ( ( line_index, line) ) = layout. line_for_byte_index ( byte_index) {
23
25
path. line_index = line_index as u32 ;
24
- for ( run_index , run) in line. runs ( ) . enumerate ( ) {
25
- path. run_index = run_index as u32 ;
26
+ for run in line. runs ( ) {
27
+ path. run_index = run . index ;
26
28
if !run. text_range ( ) . contains ( & byte_index) {
27
29
continue ;
28
30
}
@@ -44,32 +46,39 @@ impl<'a, B: Brush> Cluster<'a, B> {
44
46
path. line_index = line_index as u32 ;
45
47
let mut offset = line. metrics ( ) . offset ;
46
48
let last_run_index = line. len ( ) . saturating_sub ( 1 ) ;
47
- for ( run_index, run) in line. runs ( ) . enumerate ( ) {
48
- let is_last_run = run_index == last_run_index;
49
- let run_advance = run. advance ( ) ;
50
- path. run_index = run_index as u32 ;
51
- path. logical_index = 0 ;
52
- if x > offset + run_advance && !is_last_run {
53
- offset += run_advance;
54
- continue ;
55
- }
56
- let last_cluster_index = run. cluster_range ( ) . len ( ) . saturating_sub ( 1 ) ;
57
- for ( visual_index, cluster) in run. visual_clusters ( ) . enumerate ( ) {
58
- let is_last_cluster = is_last_run && visual_index == last_cluster_index;
59
- path. logical_index =
60
- run. visual_to_logical ( visual_index) . unwrap_or_default ( ) as u32 ;
61
- let cluster_advance = cluster. advance ( ) ;
62
- let edge = offset;
63
- offset += cluster_advance;
64
- if x > offset && !is_last_cluster {
65
- continue ;
49
+ for item in line. items_nonpositioned ( ) {
50
+ match item {
51
+ LineItem :: Run ( run) => {
52
+ let is_last_run = run. index as usize == last_run_index;
53
+ let run_advance = run. advance ( ) ;
54
+ path. run_index = run. index ;
55
+ path. logical_index = 0 ;
56
+ if x > offset + run_advance && !is_last_run {
57
+ offset += run_advance;
58
+ continue ;
59
+ }
60
+ let last_cluster_index = run. cluster_range ( ) . len ( ) . saturating_sub ( 1 ) ;
61
+ for ( visual_index, cluster) in run. visual_clusters ( ) . enumerate ( ) {
62
+ let is_last_cluster = is_last_run && visual_index == last_cluster_index;
63
+ path. logical_index =
64
+ run. visual_to_logical ( visual_index) . unwrap_or_default ( ) as u32 ;
65
+ let cluster_advance = cluster. advance ( ) ;
66
+ let edge = offset;
67
+ offset += cluster_advance;
68
+ if x > offset && !is_last_cluster {
69
+ continue ;
70
+ }
71
+ let side = if x <= edge + cluster_advance * 0.5 {
72
+ ClusterSide :: Left
73
+ } else {
74
+ ClusterSide :: Right
75
+ } ;
76
+ return Some ( ( path. cluster ( layout) ?, side) ) ;
77
+ }
78
+ }
79
+ LineItem :: InlineBox ( inline_box) => {
80
+ offset += inline_box. width ;
66
81
}
67
- let side = if x <= edge + cluster_advance * 0.5 {
68
- ClusterSide :: Left
69
- } else {
70
- ClusterSide :: Right
71
- } ;
72
- return Some ( ( path. cluster ( layout) ?, side) ) ;
73
82
}
74
83
}
75
84
}
@@ -246,7 +255,7 @@ impl<'a, B: Brush> Cluster<'a, B> {
246
255
for line_index in self . path . line_index ( ) ..layout. len ( ) {
247
256
let line = layout. get ( line_index) ?;
248
257
for run_index in run_index..line. len ( ) {
249
- if let Some ( run) = line. run ( run_index) {
258
+ if let Some ( run) = line. item ( run_index) . and_then ( |item| item . run ( ) ) {
250
259
if !run. cluster_range ( ) . is_empty ( ) {
251
260
return ClusterPath {
252
261
line_index : line_index as u32 ,
@@ -287,7 +296,7 @@ impl<'a, B: Brush> Cluster<'a, B> {
287
296
let line = layout. get ( line_index) ?;
288
297
let first_run = run_index. unwrap_or ( line. len ( ) ) ;
289
298
for run_index in ( 0 ..first_run) . rev ( ) {
290
- if let Some ( run) = line. run ( run_index) {
299
+ if let Some ( run) = line. item ( run_index) . and_then ( |item| item . run ( ) ) {
291
300
let range = run. cluster_range ( ) ;
292
301
if !range. is_empty ( ) {
293
302
return ClusterPath {
@@ -361,13 +370,20 @@ impl<'a, B: Brush> Cluster<'a, B> {
361
370
let line = self . path . line ( self . run . layout ) ?;
362
371
let mut offset = line. metrics ( ) . offset ;
363
372
for run_index in 0 ..=self . path . run_index ( ) {
364
- let run = line. run ( run_index) ?;
365
- if run_index != self . path . run_index ( ) {
366
- offset += run. advance ( ) ;
367
- } else {
368
- let visual_index = run. logical_to_visual ( self . path . logical_index ( ) ) ?;
369
- for cluster in run. visual_clusters ( ) . take ( visual_index) {
370
- offset += cluster. advance ( ) ;
373
+ let item = line. item ( run_index) ?;
374
+ match item {
375
+ LineItem :: Run ( run) => {
376
+ if run_index != self . path . run_index ( ) {
377
+ offset += run. advance ( ) ;
378
+ } else {
379
+ let visual_index = run. logical_to_visual ( self . path . logical_index ( ) ) ?;
380
+ for cluster in run. visual_clusters ( ) . take ( visual_index) {
381
+ offset += cluster. advance ( ) ;
382
+ }
383
+ }
384
+ }
385
+ LineItem :: InlineBox ( inline_box) => {
386
+ offset += inline_box. width ;
371
387
}
372
388
}
373
389
}
@@ -441,7 +457,7 @@ impl ClusterPath {
441
457
442
458
/// Returns the run for this path and the specified layout.
443
459
pub fn run < ' a , B : Brush > ( & self , layout : & ' a Layout < B > ) -> Option < Run < ' a , B > > {
444
- self . line ( layout) ?. run ( self . run_index ( ) )
460
+ self . line ( layout) ?. item ( self . run_index ( ) ) ? . run ( )
445
461
}
446
462
447
463
/// Returns the cluster for this path and the specified layout.
0 commit comments