just_font_scan
Dart package to scan system font families and their supported weights using platform-native APIs.
- Windows: DirectWrite COM API (
dwrite.dll) viadart:ffi - macOS: CoreText framework via
dart:ffi
Features
- Retrieves all system font families grouped by the platform's native family grouping (e.g. "Source Code Pro" is one family with weights 200--900, not separate entries per variant)
- Reports supported font weights (100--950 on Windows, 100--900 on macOS) per family
- Results cached after first scan; repeated
clearCache() → scan()cycles are memory-safe - No native build step -- pure
dart:ffiwith system libraries
Installation
Add to your pubspec.yaml:
dependencies:
just_font_scan:
git:
url: https://github.com/kihyun1998/just_font_scan.git
API Reference
FontFamily class
Represents a single system font family.
| Property | Type | Description |
|---|---|---|
name |
String |
Font family name (e.g. 'Arial', 'Source Code Pro'). |
weights |
List<int> |
Supported font weights in ascending order. Values follow the CSS/OpenType convention (see weight table below). |
FontFamily supports equality comparison (==) and can be used as a map key.
JustFontScan class
All methods are static. No instantiation needed.
JustFontScan.scan()
static List<FontFamily> scan()
Scans all system font families. Returns a list sorted alphabetically by family name.
- Returns:
List<FontFamily>-- all font families found on the system. - Caching: Results are cached after the first call. Subsequent calls return the cached list instantly.
- Error handling: Returns an empty list
[]if the platform is unsupported or if a native API error occurs. Never throws. - Thread safety: The cache is isolate-local. Calling
scan()from different isolates triggers separate scans.
JustFontScan.clearCache()
static void clearCache()
Clears the cached scan result. The next scan() call will rescan the system. Use this if fonts have been installed or removed since the last scan.
JustFontScan.weightsFor()
static List<int> weightsFor(String familyName)
Returns the supported weights for a specific font family.
- Parameter
familyName(String): The font family name to look up. Case-insensitive (e.g.'arial'matches'Arial'). - Returns:
List<int>-- weights in ascending order. - Not found: Returns
[400]as a default when the family does not exist in the system. To distinguish "family exists with only weight 400" from "family not found", usescan()directly and search the result.
Font weight values
Standard DWRITE_FONT_WEIGHT / CSS font-weight values:
| Value | Name |
|---|---|
| 100 | Thin |
| 200 | ExtraLight |
| 300 | Light |
| 350 | SemiLight |
| 400 | Regular |
| 500 | Medium |
| 600 | SemiBold |
| 700 | Bold |
| 800 | ExtraBold |
| 900 | Black |
| 950 | ExtraBlack |
Not all fonts support every weight. A font may have any subset of these values.
macOS weight caveat
macOS CoreText reports font weight as a normalized float in the range −1.0 to 1.0. just_font_scan snaps each value to the nearest bucket in Apple's NSFontWeight table and reports the corresponding CSS weight. This is an approximation — a font whose native weight is e.g. 0.36 (between Semibold 0.30 and Bold 0.40) will be reported as 700 because it is closer to Bold. On Windows, DWRITE_FONT_WEIGHT values map 1:1, so Windows results are exact.
The CSS weight 950 (ExtraBlack) is never produced on macOS because no public NSFontWeight constant corresponds to it.
Usage
Basic scan
import 'package:just_font_scan/just_font_scan.dart';
final families = JustFontScan.scan();
// families is List<FontFamily>, sorted by name.
for (final family in families) {
print('${family.name}: ${family.weights}');
}
// Arial: [400, 700, 900]
// Calibri: [300, 400, 700]
// Source Code Pro: [200, 300, 400, 500, 600, 700, 800, 900]
// ...
Query a specific family
final weights = JustFontScan.weightsFor('Source Code Pro');
print(weights); // [200, 300, 400, 500, 600, 700, 800, 900]
final missing = JustFontScan.weightsFor('NonExistentFont');
print(missing); // [400] (default fallback)
Check if a family supports a specific weight
final weights = JustFontScan.weightsFor('Arial');
if (weights.contains(700)) {
print('Arial Bold is available');
}
Check if a family exists
final families = JustFontScan.scan();
final exists = families.any(
(f) => f.name.toLowerCase() == 'arial',
);
Rescan after font installation
JustFontScan.clearCache();
final updated = JustFontScan.scan();
Platform support
| Platform | Status | API |
|---|---|---|
| Windows | Supported | DirectWrite (IDWriteFactory) |
| macOS | Supported | CoreText (CTFontCollection) |
| Linux | Not yet | -- |
On unsupported platforms, scan() returns an empty list and weightsFor() always returns [400].
Requirements
- Dart SDK
>=3.9.2 - Windows 7+ (DirectWrite is preinstalled) or macOS 10.13+ (CoreText is preinstalled)
Libraries
- just_font_scan
- Scan system font families and their supported weights using platform-native APIs.