获取字体轮廓编程 [英] Get font outlines programatically

查看:363
本文介绍了获取字体轮廓编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是它在某种程度上可以检索字体(TTF / OTF)大纲作为Android上的曲线/一系列点?例如,如果我想用特定的字体文字转换成矢量格式?

Is it somehow possible to retrieve font (ttf/otf) outline as a curve/series of points on Android? For example, if I wanted to convert a word with specific font into a vector format?

推荐答案

因为我从来没有为Android设备开发的,我会给你做到这一点的方式,但在的Java

Since I never developed for an Android device, I will give you the way to do that, but in Java.

这是一对很好的库,但我不知道是否有可能为你使用它( C / C ++ )所以我将解释如何自己做。

This is a couple of good libraries, but I don't know if it would be possible for you to use it (C/C++) So I will explain you how to do it yourself.

您应该先使用转换你的字形状的的TextLayout 在(样式字符数据可以得出的不可变图形重新presentation)的FontRenderContext

You should in first convert your word in a shape using a TextLayout (an immutable graphical representation of styled character data that you can draw) in a FontRenderContext.

据约翰·史密斯Ĵ这里回答: http://stackoverflow.com/a/6864113/837765 ,它应该是可以使用类似于的TextLayout Android上的东西。但是,有没有的FontRenderContext 的quivalent。正如我所说的,我从来没有为Android设备开发的,但有可能是(我希望如此)的解决方法,字符转换的形状。

According to the John J Smith answer here: http://stackoverflow.com/a/6864113/837765, It should be possible to use something similar to a TextLayout on Android. But, there's no quivalent of FontRenderContext. As I said, I never developed for an Android device, but there is probably (I hope so) a workaround to convert characters in a shape.

在Java的像这样的东西应该工作(文字转换成一个Shape):

In Java Something like this should work (to convert text in a Shape):

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;
}

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

在每次迭代中,你可以得到当前段的其类型和坐标:

On each iteration, you can get the current segment, its type and the coordinates.:


  1. SEG_QUADTO 的:二次参数曲线;

  2. SEG_CUBICTO 的:一个三次参数曲线;

  3. SEG_LINETO 的:指定线的终点;

  4. SEG_MOVETO 的:一个点,指定新子路径的起始位置

  1. SEG_QUADTO: a quadratic parametric curve;
  2. SEG_CUBICTO : a cubic parametric curve;
  3. SEG_LINETO : specifies the end point of a line;
  4. SEG_MOVETO : a point that specifies the starting location for a new subpath.

在这一点上,你应该阅读有关贝塞尔曲线这里和<一个HREF =htt​​p://pfaedit.sourceforge.net/bezier.html相对=nofollow>这里。

At this point, you should read about Bézier curve here and here.

您将了解到:

不限二次样条可以是pssed作为立方(其中立方术语前$ P $
  为零)。立方的端点将是相同的
  二次的。

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

CP0 = QP0 CP3 = QP2

有关立方的两个控制点分别是:

The two control points for the cubic are:

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

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

因此​​,从TrueType字体转换为PostScript是微不足道的。

So converting from TrueType to PostScript is trivial.

在Java中这样的事情应该工作:

In Java Something like this should work:

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;
}

我创建了一个到位桶示范项目,也许它可以帮助你。
https://bitbucket.org/pieralexandre/fontshape

初​​始形状文本(提纲后变换):

Initial shape text (after outline transformation):

在形状点:

只有几点:

和所有点的输出:

(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项目(我希望)

I know you cannot use Graphics2D (I used it for the UI) in Android, but you should be able to use my solution for an Android Project (I hope).

在这之后,你可能能够(与贝塞尔曲线的帮助下)重新创建你的曲线。

After that, you could be able (with the help of Bézier curve) to recreate your curves.

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

Also, there's a couple of other good tools here. take a look at this one:

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

这是在Javascript,但也许它可以帮助你,甚至更多。

It's in Javascript, but maybe it could help you even more.

这篇关于获取字体轮廓编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆