gpt4 book ai didi

java - 以编程方式获取字体轮廓

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:54:40 26 4
gpt4 key购买 nike

是否可以通过某种方式在 Android 上将字体 (ttf/otf) 轮廓检索为一条曲线/一系列点?例如,如果我想将具有特定字体的单词转换为 vector 格式?

最佳答案

因为我从来没有为 Android 设备开发过,所以我会告诉你这样做的方法,但是在 Java .

这是几个不错的库,但我不知道您是否可以使用它 (C/C++),所以我将向您解释如何自己使用它。

您应该首先使用 TextLayout 将您的单词转换为形状(您可以绘制的样式字符数据的不可变图形表示)在 FontRenderContext 中.

根据 John J Smith 的回答:https://stackoverflow.com/a/6864113/837765 , 应该可以使用类似于 TextLayout 的东西在安卓系统上。但是,没有 FontRenderContext 的等价物。 .正如我所说,我从未为 Android 设备开发过,但可能(我希望如此)有一种将字符转换为形状的解决方法。

在 Java 中这样的东西应该可以工作(将文本转换为形状):

public Shape getShape(String text, Font font, Point from) {
FontRenderContext context = new FontRenderContext(null, false, false);

GeneralPath shape = new GeneralPath();
TextLayout layout = new TextLayout(text, font, context);

Shape outline = layout.getOutline(null);
shape.append(outline, true);

return shape;
}

然后,您应该找到形状边界。这里并不难,因为你的形状可以直接给你路径迭代器 shape.getPathIterator(null)

在每次迭代中,您可以获得当前段,its type和坐标。:

  1. SEG_QUADTO:二次参数曲线;
  2. SEG_CUBICTO:三次参数曲线;
  3. SEG_LINETO : 指定直线的终点;
  4. SEG_MOVETO :指定新子路径起始位置的点。

此时,您应该阅读贝塞尔曲线 herehere .

您将了解到:

Any quadratic spline can be expressed as a cubic (where the cubic term is zero). The end points of the cubic will be the same as the quadratic's.

CP0 = QP0 CP3 = QP2

The two control points for the cubic are:

CP1 = QP0 + 2/3 *(QP1-QP0) CP2 = CP1 + 1/3 *(QP2-QP0)

因此从 TrueType 转换为 PostScript 是微不足道的。

在 Java 中这样的东西应该可以工作:

public List<Point> getPoints(Shape shape) {
List<Point> out = new ArrayList<Point>();
PathIterator iterator = shape.getPathIterator(null);

double[] coordinates = new double[6];
double x = 0, y = 0;

while (!iterator.isDone()) {

double x1 = coordinates[0];
double y1 = coordinates[1];

double x2 = coordinates[2];
double y2 = coordinates[3];

double x3 = coordinates[4];
double y3 = coordinates[5];

switch (iterator.currentSegment(coordinates)) {
case PathIterator.SEG_QUADTO:
x3 = x2;
y3 = y2;

x2 = x1 + 1 / 3f * (x2 - x1);
y2 = y1 + 1 / 3f * (y2 - y1);

x1 = x + 2 / 3f * (x1 - x);
y1 = y + 2 / 3f * (y1 - y);

out.add(new Point(x3, y3));

x = x3;
y = y3;
break;

case PathIterator.SEG_CUBICTO:
out.add(new Point(x3, y3));
x = x3;
y = y3;
break;
case PathIterator.SEG_LINETO:
out.add(new Point(x1, y1));
x = x1;
y = y1;
break;
case PathIterator.SEG_MOVETO:
out.add(new Point(x1, y1));
x = x1;
y = y1;
break;
}
iterator.next();
}

return out;
}

我在 Bitbucket 上创建了一个演示项目,也许它可以帮助你。 https://bitbucket.org/pieralexandre/fontshape

初始形状文本(轮廓变换后):

enter image description here

形状上的点:

enter image description here

只有点:

enter image description here

以及所有点的输出:

(0.0,0.0)
(9.326171875,200.0)
(9.326171875,127.734375)
(0.0,0.0)
(50.7080078125,130.126953125)
(62.158203125,138.232421875)
(69.82421875,162.158203125)
(60.302734375,190.087890625)
(50.78125,200.0)
//...

我知道你不能使用 Graphics2D (我将它用于 UI)在 Android 中,但您应该能够将我的解决方案用于 Android 项目(我希望)。

之后,您可以(在贝塞尔曲线的帮助下)重新创建曲线。

此外,这里还有一些其他的好工具。看看这个:

http://nodebox.github.io/opentype.js/

它是用 Javascript 编写的,但也许它可以为您提供更多帮助。

关于java - 以编程方式获取字体轮廓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26563073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com