1- use crate :: atlas:: Atlas ;
1+ use crate :: atlas:: { Atlas , AtlasContent } ;
2+ use cosmic_text:: { SubpixelBin , SwashContent , SwashImage } ;
23use rect_packer:: Rect ;
34use std:: collections:: HashMap ;
45
@@ -8,10 +9,29 @@ pub struct GlyphInfo {
89 pub metrics : fontdue:: Metrics ,
910}
1011
12+ #[ derive( Copy , Clone , Debug ) ]
13+ pub struct AtlasInfo {
14+ pub rect : Option < Rect > ,
15+ pub left : i32 ,
16+ pub top : i32 ,
17+ pub colored : bool ,
18+ }
19+
1120pub struct GlyphCache {
12- pub atlas : Atlas ,
21+ pub mask_atlas : Atlas ,
22+ pub color_atlas : Atlas ,
1323 pub font : fontdue:: Font ,
1424 info : HashMap < ( char , u32 ) , GlyphInfo > ,
25+ atlas_infos : HashMap <
26+ (
27+ cosmic_text:: fontdb:: ID ,
28+ u16 ,
29+ u32 ,
30+ ( SubpixelBin , SubpixelBin ) ,
31+ ) ,
32+ AtlasInfo ,
33+ > ,
34+ svg_infos : HashMap < Vec < u8 > , HashMap < ( u32 , u32 ) , AtlasInfo > > ,
1535}
1636
1737impl GlyphCache {
@@ -22,10 +42,82 @@ impl GlyphCache {
2242 let font = include_bytes ! ( "fonts/Anodina-Regular.ttf" ) as & [ u8 ] ;
2343
2444 Self {
25- atlas : Atlas :: new ( device) ,
45+ mask_atlas : Atlas :: new ( device, AtlasContent :: Mask ) ,
46+ color_atlas : Atlas :: new ( device, AtlasContent :: Color ) ,
2647 font : fontdue:: Font :: from_bytes ( font, settings) . unwrap ( ) ,
2748 info : HashMap :: new ( ) ,
49+ atlas_infos : HashMap :: new ( ) ,
50+ svg_infos : HashMap :: new ( ) ,
51+ }
52+ }
53+
54+ pub fn get_svg_mask (
55+ & mut self ,
56+ hash : & [ u8 ] ,
57+ width : u32 ,
58+ height : u32 ,
59+ image : impl FnOnce ( ) -> Vec < u8 > ,
60+ ) -> AtlasInfo {
61+ if !self . svg_infos . contains_key ( hash) {
62+ self . svg_infos . insert ( hash. to_vec ( ) , HashMap :: new ( ) ) ;
63+ }
64+
65+ {
66+ let svg_infos = self . svg_infos . get ( hash) . unwrap ( ) ;
67+ if let Some ( info) = svg_infos. get ( & ( width, height) ) {
68+ return info. clone ( ) ;
69+ }
2870 }
71+
72+ let data = image ( ) ;
73+ let rect = self . color_atlas . add_region ( & data, width, height) ;
74+ let info = AtlasInfo {
75+ rect,
76+ left : 0 ,
77+ top : 0 ,
78+ colored : true ,
79+ } ;
80+
81+ let svg_infos = self . svg_infos . get_mut ( hash) . unwrap ( ) ;
82+ svg_infos. insert ( ( width, height) , info. clone ( ) ) ;
83+
84+ info
85+ }
86+
87+ pub fn get_glyph_mask < ' a > (
88+ & mut self ,
89+ font_id : cosmic_text:: fontdb:: ID ,
90+ glyph_id : u16 ,
91+ size : u32 ,
92+ subpx : ( SubpixelBin , SubpixelBin ) ,
93+ image : impl FnOnce ( ) -> SwashImage ,
94+ ) -> AtlasInfo {
95+ let key = ( font_id, glyph_id, size, subpx) ;
96+ if let Some ( rect) = self . atlas_infos . get ( & key) {
97+ return * rect;
98+ }
99+
100+ let image = image ( ) ;
101+ let rect = match image. content {
102+ SwashContent :: Mask => self . mask_atlas . add_region (
103+ & image. data ,
104+ image. placement . width ,
105+ image. placement . height ,
106+ ) ,
107+ SwashContent :: SubpixelMask | SwashContent :: Color => self . color_atlas . add_region (
108+ & image. data ,
109+ image. placement . width ,
110+ image. placement . height ,
111+ ) ,
112+ } ;
113+ let info = AtlasInfo {
114+ rect,
115+ left : image. placement . left ,
116+ top : image. placement . top ,
117+ colored : image. content != SwashContent :: Mask ,
118+ } ;
119+ self . atlas_infos . insert ( key, info) ;
120+ info
29121 }
30122
31123 pub fn get_glyph ( & mut self , c : char , size : f32 ) -> GlyphInfo {
@@ -52,7 +144,7 @@ impl GlyphCache {
52144 */
53145
54146 let rect =
55- self . atlas
147+ self . mask_atlas
56148 . add_region ( & data, metrics. width as u32 , metrics. height as u32 ) ;
57149
58150 let info = GlyphInfo { rect, metrics } ;
@@ -64,19 +156,20 @@ impl GlyphCache {
64156 }
65157
66158 pub fn update ( & mut self , device : & wgpu:: Device , encoder : & mut wgpu:: CommandEncoder ) {
67- self . atlas . update ( device, encoder) ;
159+ self . mask_atlas . update ( device, encoder) ;
160+ self . color_atlas . update ( device, encoder) ;
68161 }
69162
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 ( )
163+ pub fn check_usage ( & mut self ) {
164+ if self . mask_atlas . usage ( ) > 0.7 || self . color_atlas . usage ( ) > 0.7 {
165+ self . clear ( ) ;
166+ }
76167 }
77168
78169 pub fn clear ( & mut self ) {
79170 self . info . clear ( ) ;
80- self . atlas . clear ( ) ;
171+ self . mask_atlas . clear ( ) ;
172+ self . color_atlas . clear ( ) ;
173+ self . atlas_infos . clear ( ) ;
81174 }
82175}
0 commit comments