1- use crate :: atlas:: Atlas ;
1+ use crate :: atlas:: { Atlas , AtlasContent } ;
22use rect_packer:: Rect ;
3- use std:: collections:: HashMap ;
3+ use std:: {
4+ collections:: HashMap ,
5+ hash:: { Hash , Hasher } ,
6+ sync:: Arc ,
7+ } ;
48
59#[ derive( Copy , Clone , Debug ) ]
610pub struct GlyphInfo {
711 pub rect : Option < Rect > ,
812 pub metrics : fontdue:: Metrics ,
913}
1014
11- pub struct GlyphCache {
12- pub atlas : Atlas ,
15+ #[ derive( Clone , Eq ) ]
16+ pub struct ImageId {
17+ id : Arc < bool > ,
18+ }
19+
20+ impl ImageId {
21+ pub fn new ( ) -> Self {
22+ Self {
23+ id : Arc :: new ( false ) ,
24+ }
25+ }
26+ }
27+
28+ impl PartialEq for ImageId {
29+ fn eq ( & self , other : & Self ) -> bool {
30+ Arc :: ptr_eq ( & self . id , & other. id )
31+ }
32+ }
33+
34+ impl Hash for ImageId {
35+ fn hash < H > ( & self , state : & mut H )
36+ where
37+ H : Hasher ,
38+ {
39+ ( Arc :: as_ptr ( & self . id ) as usize ) . hash ( state)
40+ }
41+ }
42+
43+ #[ derive( Copy , Clone , Debug ) ]
44+ pub struct AtlasImage {
45+ pub rect : Option < Rect > ,
46+ }
47+
48+ pub struct AtlasCache {
49+ pub mask_atlas : Atlas ,
50+ pub color_atlas : Atlas ,
1351 pub font : fontdue:: Font ,
14- info : HashMap < ( char , u32 ) , GlyphInfo > ,
52+ glyphs : HashMap < ( char , u32 ) , GlyphInfo > ,
53+ mask_images : HashMap < ImageId , AtlasImage > ,
54+ color_images : HashMap < ImageId , AtlasImage > ,
1555}
1656
17- impl GlyphCache {
57+ impl AtlasCache {
1858 pub fn new ( device : & wgpu:: Device ) -> Self {
1959 let mut settings = fontdue:: FontSettings :: default ( ) ;
2060 settings. collection_index = 0 ;
2161 settings. scale = 100.0 ;
2262 let font = include_bytes ! ( "fonts/Anodina-Regular.ttf" ) as & [ u8 ] ;
2363
2464 Self {
25- atlas : Atlas :: new ( device) ,
65+ mask_atlas : Atlas :: new ( device, AtlasContent :: Mask ) ,
66+ color_atlas : Atlas :: new ( device, AtlasContent :: Color ) ,
2667 font : fontdue:: Font :: from_bytes ( font, settings) . unwrap ( ) ,
27- info : HashMap :: new ( ) ,
68+ glyphs : HashMap :: new ( ) ,
69+ mask_images : HashMap :: new ( ) ,
70+ color_images : HashMap :: new ( ) ,
2871 }
2972 }
3073
74+ pub fn get_mask_image (
75+ & mut self ,
76+ id : ImageId ,
77+ width : u32 ,
78+ height : u32 ,
79+ image : impl FnOnce ( ) -> Vec < u8 > ,
80+ ) -> AtlasImage {
81+ let mask_atlas = & mut self . mask_atlas ;
82+ * self . mask_images . entry ( id) . or_insert_with ( || AtlasImage {
83+ rect : mask_atlas. add_region ( & image ( ) , width, height) ,
84+ } )
85+ }
86+
87+ pub fn get_color_image (
88+ & mut self ,
89+ id : ImageId ,
90+ width : u32 ,
91+ height : u32 ,
92+ image : impl FnOnce ( ) -> Vec < u8 > ,
93+ ) -> AtlasImage {
94+ let color_atlas = & mut self . color_atlas ;
95+ * self . color_images . entry ( id) . or_insert_with ( || AtlasImage {
96+ rect : color_atlas. add_region ( & image ( ) , width, height) ,
97+ } )
98+ }
99+
31100 pub fn get_glyph ( & mut self , c : char , size : f32 ) -> GlyphInfo {
32101 let factor = 65536.0 ;
33102
34103 // Convert size to fixed point so we can hash it.
35104 let size_fixed_point = ( size * factor) as u32 ;
36105
37106 // Do we already have a glyph?
38- match self . info . get ( & ( c, size_fixed_point) ) {
107+ match self . glyphs . get ( & ( c, size_fixed_point) ) {
39108 Some ( info) => * info,
40109 None => {
41110 let ( metrics, data) = self . font . rasterize ( c, size_fixed_point as f32 / factor) ;
@@ -52,31 +121,31 @@ impl GlyphCache {
52121 */
53122
54123 let rect =
55- self . atlas
124+ self . mask_atlas
56125 . add_region ( & data, metrics. width as u32 , metrics. height as u32 ) ;
57126
58127 let info = GlyphInfo { rect, metrics } ;
59128
60- self . info . insert ( ( c, size_fixed_point) , info) ;
129+ self . glyphs . insert ( ( c, size_fixed_point) , info) ;
61130 info
62131 }
63132 }
64133 }
65134
66135 pub fn update ( & mut self , device : & wgpu:: Device , encoder : & mut wgpu:: CommandEncoder ) {
67- self . atlas . update ( device, encoder) ;
136+ self . mask_atlas . update ( device, encoder) ;
137+ self . color_atlas . update ( device, encoder) ;
68138 }
69139
70- pub fn create_view ( & self ) -> wgpu:: TextureView {
71- self . atlas . create_view ( )
72- }
73-
74- pub fn usage ( & self ) -> f32 {
75- self . atlas . usage ( )
76- }
77-
78- pub fn clear ( & mut self ) {
79- self . info . clear ( ) ;
80- self . atlas . clear ( ) ;
140+ pub fn check_usage ( & mut self ) {
141+ if self . mask_atlas . usage ( ) > 0.7 {
142+ self . glyphs . clear ( ) ;
143+ self . mask_atlas . clear ( ) ;
144+ self . mask_images . clear ( ) ;
145+ }
146+ if self . color_atlas . usage ( ) > 0.7 {
147+ self . color_atlas . clear ( ) ;
148+ self . color_images . clear ( ) ;
149+ }
81150 }
82151}
0 commit comments