@@ -31,7 +31,7 @@ use crate::space::SpaceMapper;
31
31
use crate :: visibility:: { PrimitiveVisibilityFlags , VisibilityState } ;
32
32
use smallvec:: SmallVec ;
33
33
use std:: { f32, i32, usize, mem} ;
34
- use crate :: util:: { project_rect, MaxRect , MatrixHelpers , TransformedRectKind } ;
34
+ use crate :: util:: { project_rect, MaxRect , MatrixHelpers , TransformedRectKind , ScaleOffset } ;
35
35
use crate :: segment:: EdgeAaSegmentMask ;
36
36
37
37
// Special sentinel value recognized by the shader. It is considered to be
@@ -1353,43 +1353,39 @@ impl BatchBuilder {
1353
1353
1354
1354
let surface = & ctx. surfaces [ raster_config. surface_index . 0 ] ;
1355
1355
1356
- // If we are drawing with snapping enabled, the local rect of the prim must be in the raster
1357
- // space, to avoid situations where there is a 180deg rotation in between the root and primitive
1358
- // space not being correctly applied.
1359
- let prim_header = if surface. surface_spatial_node_index == surface. raster_spatial_node_index {
1360
- PrimitiveHeader {
1361
- local_rect : prim_rect,
1362
- local_clip_rect : prim_info. combined_local_clip_rect ,
1363
- specific_prim_address : prim_cache_address,
1364
- transform_id,
1365
- }
1356
+ // If we are drawing with snapping enabled, form a simple transform that just applies
1357
+ // the scale / translation from the raster transform. Otherwise, in edge cases where the
1358
+ // intermediate surface has a non-identity but axis-aligned transform (e.g. a 180 degree
1359
+ // rotation) it can be applied twice.
1360
+ let transform_id = if surface. surface_spatial_node_index == surface. raster_spatial_node_index {
1361
+ transform_id
1366
1362
} else {
1367
1363
let map_local_to_raster = SpaceMapper :: new_with_target (
1368
- surface . raster_spatial_node_index ,
1364
+ root_spatial_node_index ,
1369
1365
surface. surface_spatial_node_index ,
1370
1366
LayoutRect :: max_rect ( ) ,
1371
1367
ctx. spatial_tree ,
1372
1368
) ;
1373
1369
1374
- let prim_rect = map_local_to_raster
1370
+ let raster_rect = map_local_to_raster
1375
1371
. map ( & prim_rect)
1376
1372
. unwrap ( ) ;
1377
- let local_clip_rect = map_local_to_raster
1378
- . map ( & prim_info. combined_local_clip_rect )
1379
- . unwrap ( ) ;
1380
- let transform_id = transforms
1381
- . get_id (
1382
- surface. raster_spatial_node_index ,
1383
- root_spatial_node_index,
1384
- ctx. spatial_tree ,
1385
- ) ;
1386
1373
1387
- PrimitiveHeader {
1388
- local_rect : prim_rect,
1389
- local_clip_rect,
1390
- specific_prim_address : prim_cache_address,
1391
- transform_id,
1392
- }
1374
+ let sx = ( raster_rect. max . x - raster_rect. min . x ) / ( prim_rect. max . x - prim_rect. min . x ) ;
1375
+ let sy = ( raster_rect. max . y - raster_rect. min . y ) / ( prim_rect. max . y - prim_rect. min . y ) ;
1376
+
1377
+ let tx = raster_rect. min . x - sx * prim_rect. min . x ;
1378
+ let ty = raster_rect. min . y - sy * prim_rect. min . y ;
1379
+
1380
+ let transform = ScaleOffset :: new ( sx, sy, tx, ty) ;
1381
+ transforms. get_custom ( transform. to_transform ( ) )
1382
+ } ;
1383
+
1384
+ let prim_header = PrimitiveHeader {
1385
+ local_rect : prim_rect,
1386
+ local_clip_rect : prim_info. combined_local_clip_rect ,
1387
+ specific_prim_address : prim_cache_address,
1388
+ transform_id,
1393
1389
} ;
1394
1390
1395
1391
let mut is_opaque = prim_info. clip_task_index == ClipTaskIndex :: INVALID
0 commit comments