基于路径绘制的无抗锯齿(No Anti-Alias)文本渲染插件。
- ✅ 路径绘制:解析 TTF 字体文件,通过矢量路径绘制文本
- ✅ 无抗锯齿:禁用抗锯齿渲染,获得清晰锐利的边缘
- ✅ 合成加粗:使用描边+填充技术模拟加粗效果,无需额外字体文件
- ✅ 合成斜体:使用 Matrix4 剪切变换实现斜体效果
- ✅ 精确缩放:使用 unitsPerEm 计算精确的缩放比例,与原生 Text 大小一致
- ✅ 简洁 API:参考 Flutter Text widget API 设计,易于使用
在项目中添加 TTF 字体文件到 assets 文件夹:
# pubspec.yaml
flutter:
assets:
- assets/微软雅黑.ttfimport 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_noaa_text/flutter_noaa_text.dart';
// 加载字体
final data = await rootBundle.load('assets/微软雅黑.ttf');
final parser = TtfParser();
final font = parser.parse(data.buffer.asUint8List());NoaaText(
'你好世界',
font: font,
style: NoaaTextStyle(
fontSize: 48,
color: Colors.black,
fontWeight: FontWeight.bold, // 合成加粗
fontStyle: FontStyle.italic, // 合成斜体
letterSpacing: 2.0, // 字符间距
disableAntiAlias: true, // 禁用抗锯齿
),
)| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fontSize |
double? |
14.0 | 字体大小(像素) |
color |
Color? |
黑色 | 文本颜色 |
fontWeight |
FontWeight? |
normal | 字体粗细(用于判断是否加粗) |
fontStyle |
FontStyle? |
normal | 字体样式(用于判断是否斜体) |
letterSpacing |
double? |
0.0 | 字符间距 |
height |
double? |
1.0 | 行高倍数 |
disableAntiAlias |
bool? |
true | 是否禁用抗锯齿 |
boldStrokeWidthFactor |
double? |
0.03 | 加粗描边宽度系数 |
italicSkewFactor |
double? |
-0.2 | 斜体剪切系数 |
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_noaa_text/flutter_noaa_text.dart';
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TtfFont? font;
@override
void initState() {
super.initState();
_loadFont();
}
Future<void> _loadFont() async {
final data = await rootBundle.load('assets/微软雅黑.ttf');
final parser = TtfParser();
setState(() {
font = parser.parse(data.buffer.asUint8List());
});
}
@override
Widget build(BuildContext context) {
if (font == null) {
return CircularProgressIndicator();
}
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 普通文本
NoaaText(
'你好世界',
font: font!,
style: NoaaTextStyle(fontSize: 48),
),
SizedBox(height: 20),
// 加粗文本
NoaaText(
'Bold Text',
font: font!,
style: NoaaTextStyle(
fontSize: 48,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 20),
// 斜体文本
NoaaText(
'Italic Text',
font: font!,
style: NoaaTextStyle(
fontSize: 48,
fontStyle: FontStyle.italic,
),
),
],
),
),
);
}
}使用 text_to_path_maker 库解析 TTF 字体文件,通过 unitsPerEm 计算精确的缩放比例:
scale = fontSize / unitsPerEm使用描边+填充技术:
- 先绘制描边:
strokeWidth = fontSize * 0.03 - 再填充中心
使用 Matrix4 水平剪切变换:
Matrix4.identity()..setEntry(0, 1, -0.2) // 约 12 度倾斜| 特性 | 原生 Text | NoaaText |
|---|---|---|
| 渲染方式 | 系统字体引擎 | 矢量路径 |
| 抗锯齿 | 默认开启 | 可禁用 |
| 加粗/斜体 | 需要字体文件 | 合成生成 |
| 动画/特效 | 有限 | 可扩展 |
| 性能 | 高 | 中等 |
- 进行对比时请使用相同的字体文件(示例中
Text与NoaaText均使用fzwb.ttf)。 - NoaaText 以字体的
advanceWidth作为测量依据,并按unitsPerEm线性缩放:pixel = advanceWidth * fontSize / unitsPerEm。 - 若字体缺少某个字符的 glyph,会退回到边界估算/启发式宽度(中文≈1.0×size,西文≈0.6×size),可能导致偏差;建议选择字符集完整的字体。
- 暂未实现 kerning/ligature/shaping,字偶距与连字在少数字体上可能与原生引擎存在 1px 级误差。
- 修复
cmapFormat 4 解析条件(由== 0改为== null),避免遗漏 glyph 映射,解决长英文/数字串宽度被低估的问题。 - 新增
charCode -> glyphId快速映射,使getGlyphIdForCharacter由 O(n) 扫描变为 O(1) 查找,测量更稳定。
MIT