【发布时间】:2018-08-16 17:40:59
【问题描述】:
我需要知道一段文本的确切范围——相当于 Android 的getTextBounds。我意识到这与 Flutter 的设计有些背道而驰,但我以非传统方式使用文本(就好像文本以精确的位置和大小嵌入到艺术图片中一样)。
我尝试了三种方法:
-
TextPainter的minIntrinsicWidth和height。来源如下。这会产生一个四面都有空间的边界框:我需要该矩形的边正对着“8”的黑色像素。 (在这种特殊情况下,
width和maxIntrinsicWidth给出与minIntrinsicWidth相同的值;另外,preferredLineHeight给出与height相同的值。) Paragraph'sgetBoxesForRange-- 与 TextPainter 的结果基本相同。FittedBox-- 也留下空格,无论BoxFit枚举值如何。我以this answer 为起点。
TextPainter 代码如下。 (我意识到这是低效的;在获得所需的边界框之前我不在乎。我使用场景/图片/等希望在较低级别找到合适的功能。)
import 'dart:ui';
import 'dart:typed_data';
import 'package:flutter/painting.dart';
const black = Color(0xff000000);
const white = Color(0xffffffff);
final identityTransform = new Float64List(16)
..[0] = 1.0
..[5] = 1.0
..[10] = 1.0
..[15] = 1.0;
TextPainter createTextPainter() {
return new TextPainter(
text: new TextSpan(
text: '8',
style: new TextStyle(
color: black,
fontSize: 200.0,
fontFamily: "Roboto",
),
),
textDirection: TextDirection.ltr,
)..layout();
}
void drawBackground(Canvas canvas, Rect screen) {
canvas.drawRect(
screen,
new Paint()
..color = white
..style = PaintingStyle.fill);
}
Picture createPicture() {
final recorder = new PictureRecorder();
final screen = Offset.zero & window.physicalSize;
final canvas = new Canvas(recorder, screen);
final offset = screen.center;
final painter = createTextPainter();
final bounds = offset & Size(painter.minIntrinsicWidth, painter.height);
drawBackground(canvas, screen);
painter.paint(canvas, offset);
canvas.drawRect(
bounds,
new Paint()
..color = black
..style = PaintingStyle.stroke
..strokeWidth = 3.0);
return recorder.endRecording();
}
Scene createScene() {
final builder = new SceneBuilder()
..pushTransform(identityTransform)
..addPicture(Offset.zero, createPicture())
..pop();
return builder.build();
}
void beginFrame(Duration timeStamp) {
window.render(createScene());
}
void main() {
window.onBeginFrame = beginFrame;
window.scheduleFrame();
}
【问题讨论】:
-
您使用的是哪种字体?您确定字体本身在字形周围没有空格吗?
-
我无法想象默认错误会像这样被窃听(这甚至可能用 ttf 吗?),但无论如何我添加了
fontFamily: "Roboto",结果是一样的。 -
为了清楚起见,Android 的 getTextBounds 给出了矩形,使得每一边大麦都接触到链接到图像中“8”的黑色像素,我用 Roboto 进行了测试。
-
好吧。我只是用衬线字体试了一下,有些字符确实碰到了盒子的水平边缘——但这对你没有多大帮助。似乎颤动在内部做了一些事情来分隔字符......
-
你可能是SOL直接使用flutter支持的东西。我可以给你一个替代方案,但这将是相当多的工作......这取决于你想投入多少时间以及你实际需要做多少文字(如果它是
artistic,正如你所说,我假设没有那么多)。