(&mut self, font_idx: usize, ch: char, size: u32)
| 145 | } |
| 146 | |
| 147 | fn rasterize_glyph(&mut self, font_idx: usize, ch: char, size: u32) -> &GlyphInfo { |
| 148 | let key = (font_idx, ch, size); |
| 149 | if self.glyph_cache.contains_key(&key) { |
| 150 | return &self.glyph_cache[&key]; |
| 151 | } |
| 152 | |
| 153 | let font = &self.fonts[font_idx]; |
| 154 | let (metrics, bitmap) = font.rasterize(ch, size as f32); |
| 155 | |
| 156 | let gw = metrics.width as u32; |
| 157 | let gh = metrics.height as u32; |
| 158 | |
| 159 | if self.atlas_cursor_x + gw > self.atlas_width { |
| 160 | self.atlas_cursor_x = 0; |
| 161 | self.atlas_cursor_y += self.atlas_row_height; |
| 162 | self.atlas_row_height = 0; |
| 163 | } |
| 164 | |
| 165 | let ax = self.atlas_cursor_x; |
| 166 | let ay = self.atlas_cursor_y; |
| 167 | |
| 168 | for row in 0..gh { |
| 169 | for col in 0..gw { |
| 170 | let src = (row * gw + col) as usize; |
| 171 | let dst = (((ay + row) * self.atlas_width + ax + col) * 4) as usize; |
| 172 | if src < bitmap.len() && dst + 3 < self.atlas_data.len() { |
| 173 | let alpha = bitmap[src]; |
| 174 | self.atlas_data[dst] = 255; |
| 175 | self.atlas_data[dst + 1] = 255; |
| 176 | self.atlas_data[dst + 2] = 255; |
| 177 | self.atlas_data[dst + 3] = alpha; |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | self.atlas_cursor_x += gw + 1; |
| 183 | if gh + 1 > self.atlas_row_height { |
| 184 | self.atlas_row_height = gh + 1; |
| 185 | } |
| 186 | self.atlas_dirty = true; |
| 187 | |
| 188 | self.glyph_cache.insert(key, GlyphInfo { |
| 189 | atlas_x: ax, |
| 190 | atlas_y: ay, |
| 191 | width: gw, |
| 192 | height: gh, |
| 193 | advance: metrics.advance_width, |
| 194 | x_offset: metrics.xmin as f32, |
| 195 | y_offset: metrics.ymin as f32, |
| 196 | }); |
| 197 | |
| 198 | &self.glyph_cache[&key] |
| 199 | } |
| 200 | |
| 201 | fn ensure_atlas_uploaded(&mut self, renderer: &mut Renderer) { |
| 202 | if !self.atlas_dirty { return; } |
no outgoing calls
no test coverage detected