iconDataToImageBytes function
Renders an IconData to PNG bytes for use in native platform views.
The size parameter is the logical font size of the glyph. The output
is always a square size × size logical-pixel bitmap with the glyph's
visible bounds centered inside it. This keeps the embedded icon's
effective dimensions consistent regardless of how much line-box
leading the source font reports — so native containers like UITabBar
lay out a predictable distance between icon and label.
Results are memoised per (glyph, font, size, colour, device pixel ratio); see clearIconImageCache.
Implementation
Future<Uint8List?> iconDataToImageBytes(
IconData iconData, {
double size = 25.0,
Color color = CupertinoColors.black,
}) {
final double pixelRatio =
ui.PlatformDispatcher.instance.views.first.devicePixelRatio;
final String key =
'${iconData.codePoint}|${iconData.fontFamily}|${iconData.fontPackage}'
'|${size.toStringAsFixed(3)}|${pixelRatio.toStringAsFixed(3)}'
'|${color.toARGB32()}';
final Future<Uint8List?>? cached = _iconBytesCache[key];
if (cached != null) return cached;
if (_iconBytesCache.length >= _kIconBytesCacheLimit) {
_iconBytesCache.remove(_iconBytesCache.keys.first);
}
final Future<Uint8List?> pending = _renderIconToImageBytes(
iconData,
size: size,
color: color,
pixelRatio: pixelRatio,
);
_iconBytesCache[key] = pending;
// A null result means the glyph could not be rasterised. Don't hold onto
// that — the next caller should be free to try again.
pending
.then((Uint8List? bytes) {
if (bytes == null) _iconBytesCache.remove(key);
})
.catchError((Object _) {
_iconBytesCache.remove(key);
});
return pending;
}